patents-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/dist/base.client-zZnUjoIb.js +2 -0
  4. package/dist/base.client-zZnUjoIb.js.map +1 -0
  5. package/dist/clients/base.client.d.ts +19 -0
  6. package/dist/clients/base.client.js +1 -0
  7. package/dist/clients/bigquery.client.d.ts +14 -0
  8. package/dist/clients/bigquery.client.js +66 -0
  9. package/dist/clients/bigquery.client.js.map +1 -0
  10. package/dist/clients/epo-ops.client.d.ts +13 -0
  11. package/dist/clients/epo-ops.client.js +2 -0
  12. package/dist/clients/epo-ops.client.js.map +1 -0
  13. package/dist/clients/odp.client.d.ts +52 -0
  14. package/dist/clients/odp.client.js +2 -0
  15. package/dist/clients/odp.client.js.map +1 -0
  16. package/dist/clients/patentsview.client.d.ts +38 -0
  17. package/dist/clients/patentsview.client.js +2 -0
  18. package/dist/clients/patentsview.client.js.map +1 -0
  19. package/dist/generated/odp/index.d.ts +2 -0
  20. package/dist/generated/odp/index.js +1 -0
  21. package/dist/generated/odp/types.gen.d.ts +4432 -0
  22. package/dist/generated/odp/types.gen.js +1 -0
  23. package/dist/generated/odp/zod.gen.d.ts +7504 -0
  24. package/dist/generated/odp/zod.gen.js +2 -0
  25. package/dist/generated/odp/zod.gen.js.map +1 -0
  26. package/dist/generated/patentsview/index.d.ts +2 -0
  27. package/dist/generated/patentsview/index.js +1 -0
  28. package/dist/generated/patentsview/types.gen.d.ts +2454 -0
  29. package/dist/generated/patentsview/types.gen.js +1 -0
  30. package/dist/generated/patentsview/zod.gen.d.ts +3376 -0
  31. package/dist/generated/patentsview/zod.gen.js +2 -0
  32. package/dist/generated/patentsview/zod.gen.js.map +1 -0
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +3 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/lib/config.d.ts +24 -0
  37. package/dist/lib/config.js +2 -0
  38. package/dist/lib/config.js.map +1 -0
  39. package/dist/lib/errors.d.ts +7 -0
  40. package/dist/lib/errors.js +2 -0
  41. package/dist/lib/errors.js.map +1 -0
  42. package/dist/lib/patent-number.d.ts +5 -0
  43. package/dist/lib/patent-number.js +2 -0
  44. package/dist/lib/patent-number.js.map +1 -0
  45. package/dist/lib/retry.d.ts +10 -0
  46. package/dist/lib/retry.js +2 -0
  47. package/dist/lib/retry.js.map +1 -0
  48. package/dist/lib/types.d.ts +22 -0
  49. package/dist/lib/types.js +1 -0
  50. package/dist/prompts/index.d.ts +7 -0
  51. package/dist/prompts/index.js +255 -0
  52. package/dist/prompts/index.js.map +1 -0
  53. package/dist/resources/index.d.ts +7 -0
  54. package/dist/resources/index.js +44 -0
  55. package/dist/resources/index.js.map +1 -0
  56. package/dist/server.d.ts +8 -0
  57. package/dist/server.js +2 -0
  58. package/dist/server.js.map +1 -0
  59. package/dist/tools/bigquery.tools.d.ts +7 -0
  60. package/dist/tools/bigquery.tools.js +14 -0
  61. package/dist/tools/bigquery.tools.js.map +1 -0
  62. package/dist/tools/citations.tools.d.ts +7 -0
  63. package/dist/tools/citations.tools.js +2 -0
  64. package/dist/tools/citations.tools.js.map +1 -0
  65. package/dist/tools/epo.tools.d.ts +7 -0
  66. package/dist/tools/epo.tools.js +18 -0
  67. package/dist/tools/epo.tools.js.map +1 -0
  68. package/dist/tools/index.d.ts +7 -0
  69. package/dist/tools/index.js +2 -0
  70. package/dist/tools/index.js.map +1 -0
  71. package/dist/tools/odp.tools.d.ts +7 -0
  72. package/dist/tools/odp.tools.js +2 -0
  73. package/dist/tools/odp.tools.js.map +1 -0
  74. package/dist/tools/office-actions.tools.d.ts +7 -0
  75. package/dist/tools/office-actions.tools.js +2 -0
  76. package/dist/tools/office-actions.tools.js.map +1 -0
  77. package/dist/tools/patentsview.tools.d.ts +7 -0
  78. package/dist/tools/patentsview.tools.js +2 -0
  79. package/dist/tools/patentsview.tools.js.map +1 -0
  80. package/dist/tools/ptab.tools.d.ts +7 -0
  81. package/dist/tools/ptab.tools.js +2 -0
  82. package/dist/tools/ptab.tools.js.map +1 -0
  83. package/dist/tools/utility.tools.d.ts +7 -0
  84. package/dist/tools/utility.tools.js +2 -0
  85. package/dist/tools/utility.tools.js.map +1 -0
  86. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Jordan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # patents-mcp-server
2
+
3
+ FastMCP TypeScript patent intelligence MCP server. 55 tools across USPTO, EPO, and Google Patents for IP landscape analysis, freedom-to-operate research, and patent monitoring.
4
+
5
+ ## Data Sources
6
+
7
+ | Source | Tools | Key Capability |
8
+ | ------------------- | ----- | ----------------------------------------------------------------------------- |
9
+ | **PatentsView** | 14 | US patent search, disambiguated entities (assignees, inventors, attorneys) |
10
+ | **USPTO ODP** | 29 | Applications, PTAB proceedings, citations, litigation, office actions |
11
+ | **EPO OPS** | 8 | INPADOC patent families, legal status across ~44 offices, claims/descriptions |
12
+ | **Google BigQuery** | 4 | Full-text search across 90M+ patents, citation networks, CPC analytics |
13
+
14
+ ## Quick Start
15
+
16
+ ```bash
17
+ pnpm install
18
+ cp .env.example .env # Add your API keys
19
+ pnpm build
20
+ ```
21
+
22
+ ### Run via stdio (Claude Desktop / Claude Code)
23
+
24
+ ```bash
25
+ node dist/index.js
26
+ ```
27
+
28
+ ### Run via HTTP (remote deployment)
29
+
30
+ ```bash
31
+ TRANSPORT=httpStream PORT=8080 node dist/index.js
32
+ ```
33
+
34
+ ### Test with MCP Inspector
35
+
36
+ ```bash
37
+ npx @modelcontextprotocol/inspector node dist/index.js
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ Copy `.env.example` and fill in your API keys:
43
+
44
+ ```bash
45
+ # USPTO Open Data Portal (required for ODP, PTAB, litigation, office actions)
46
+ USPTO_API_KEY=
47
+
48
+ # PatentsView (optional — works without key, key grants suspended March 2026)
49
+ PATENTSVIEW_API_KEY=
50
+
51
+ # EPO OPS (register at developers.epo.org)
52
+ EPO_CONSUMER_KEY=
53
+ EPO_CONSUMER_SECRET=
54
+
55
+ # Google BigQuery (requires GCP project with service account)
56
+ GOOGLE_APPLICATION_CREDENTIALS= # Path to service account JSON
57
+ GOOGLE_CLOUD_PROJECT= # GCP project ID
58
+ ```
59
+
60
+ Missing API keys disable related tools gracefully — the server still starts with whatever sources are configured. Use the `check-api-status` tool to verify which sources are available.
61
+
62
+ ## Tools
63
+
64
+ ### PatentsView (14 tools)
65
+
66
+ Search and retrieve US patent data with disambiguated entities.
67
+
68
+ - `patentsview-search-patents` — Full-text search by text, assignee, or inventor
69
+ - `patentsview-get-patent` — Get patent by ID
70
+ - `patentsview-search-assignees` / `get-assignee` — Disambiguated assignee search
71
+ - `patentsview-search-inventors` / `get-inventor` — Disambiguated inventor search
72
+ - `patentsview-search-attorneys` / `get-attorney` — Attorney search
73
+ - `patentsview-get-claims` — Full claims text
74
+ - `patentsview-get-description` — Patent description
75
+ - `patentsview-search-by-cpc` / `lookup-cpc` — CPC classification search
76
+ - `patentsview-search-by-ipc` / `lookup-ipc` — IPC classification search
77
+
78
+ ### USPTO ODP (12 tools)
79
+
80
+ Official USPTO Open Data Portal — applications, prosecution history, assignments.
81
+
82
+ - `odp-search-applications` — Search patent applications (2001+)
83
+ - `odp-get-application` / `metadata` / `continuity` / `assignment` / `adjustment` / `attorney` / `foreign-priority` / `transactions` / `documents`
84
+ - `odp-search-datasets` / `get-dataset` — Bulk data products
85
+
86
+ ### PTAB (7 tools)
87
+
88
+ Post-grant proceedings — IPR, PGR, CBM, ex parte appeals.
89
+
90
+ - `ptab-search-proceedings` / `get-proceeding` / `get-documents`
91
+ - `ptab-search-decisions` / `get-decision`
92
+ - `ptab-search-appeals` / `get-appeal`
93
+
94
+ ### Citations & Litigation (6 tools)
95
+
96
+ Patent citations and litigation data.
97
+
98
+ - `citations-get-enriched` / `search` / `get-metrics`
99
+ - `litigation-search` / `get-case` / `get-patent`
100
+
101
+ ### EPO OPS (8 tools)
102
+
103
+ European Patent Office — international coverage, INPADOC families, legal status.
104
+
105
+ - `epo-search-patents` — CQL search (title, abstract, applicant, inventor, CPC, date)
106
+ - `epo-get-biblio` / `abstract` / `claims` / `description` — Patent document sections
107
+ - `epo-family-lookup` — INPADOC family members across all jurisdictions
108
+ - `epo-legal-status` — Legal status across ~44 patent offices
109
+ - `epo-number-convert` — Convert between number formats
110
+
111
+ ### Google BigQuery (4 tools)
112
+
113
+ Full-text search across 90M+ patent documents. Replaces PPUBS for claims search.
114
+
115
+ - `bigquery-patent-search` — Full-text search across titles and abstracts
116
+ - `bigquery-patent-family` — Family members by INPADOC family ID
117
+ - `bigquery-citation-network` — Citation graph (depth 1 or 2)
118
+ - `bigquery-cpc-analytics` — Filing statistics by CPC classification
119
+
120
+ ### Office Actions (4 tools)
121
+
122
+ USPTO office action data (migrating to ODP in 2026).
123
+
124
+ - `office-action-get-text` / `search` / `get-citations` / `get-rejections`
125
+
126
+ ### Utility (3 tools)
127
+
128
+ - `check-api-status` — Health check all configured APIs
129
+ - `get-cpc-info` — CPC classification lookup
130
+ - `get-status-code` — USPTO status code meanings
131
+
132
+ ## Prompts
133
+
134
+ Six workflow prompt templates for common patent analysis tasks:
135
+
136
+ | Prompt | Purpose |
137
+ | ---------------------- | ------------------------------------------ |
138
+ | `prior_art_search` | Multi-source prior art search workflow |
139
+ | `patent_validity` | Structured validity analysis (102/103/112) |
140
+ | `competitor_portfolio` | Competitor patent portfolio analysis |
141
+ | `ptab_research` | PTAB proceedings research (IPR/PGR/CBM) |
142
+ | `freedom_to_operate` | FTO analysis methodology |
143
+ | `patent_landscape` | Technology area landscape mapping |
144
+
145
+ ## Resources
146
+
147
+ | URI | Description |
148
+ | ------------------------- | -------------------------------------------------------- |
149
+ | `patents://cpc/{code}` | CPC classification info |
150
+ | `patents://status-codes` | USPTO status code definitions |
151
+ | `patents://sources` | Data source overview |
152
+ | `patents://search-syntax` | Query syntax guide (PatentsView, EPO CQL, ODP, BigQuery) |
153
+
154
+ ## Development
155
+
156
+ ```bash
157
+ pnpm validate # Format + lint + typecheck + test + build
158
+ pnpm test # Run tests
159
+ pnpm build # Production build
160
+ pnpm typecheck # Type check only
161
+ ```
162
+
163
+ ## Architecture
164
+
165
+ Built with [FastMCP](https://github.com/punkpeye/fastmcp) + [Zod](https://zod.dev/) + [ts-builds](https://github.com/jordanburke/ts-builds).
166
+
167
+ ```
168
+ src/
169
+ ├── index.ts # Entry point
170
+ ├── server.ts # FastMCP instance
171
+ ├── tools/ # 55 tools across 8 modules
172
+ ├── clients/ # API clients (base, PatentsView, ODP, EPO, BigQuery)
173
+ ├── resources/ # 4 MCP resources
174
+ ├── prompts/ # 6 prompt templates
175
+ └── lib/ # Config, retry, errors, patent number normalization
176
+ ```
177
+
178
+ ## License
179
+
180
+ MIT
181
+
182
+ ## Acknowledgments
183
+
184
+ - [USPTO](https://www.uspto.gov/) - US Patent and Trademark Office
185
+ - [EPO OPS](https://www.epo.org/en/searching-for-patents/data/web-services/ops) - European Patent Office Open Patent Services
186
+ - [PatentsView](https://patentsview.org/) - USPTO patent data platform
187
+ - [Google Patents Public Data](https://console.cloud.google.com/marketplace/product/google_patents_public_datasets/google-patents-public-data) - BigQuery patent dataset
188
+
189
+ ---
190
+
191
+ **Sponsored by <a href="https://sapientsai.com/"><img src="https://sapientsai.com/images/logo.svg" alt="SapientsAI" width="20" style="vertical-align: middle;"> SapientsAI</a>** — Building agentic AI for businesses
@@ -0,0 +1,2 @@
1
+ import{withRetry as e}from"./lib/retry.js";function t(e){"@babel/helpers - typeof";return t=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},t(e)}function n(e,n){if(t(e)!=`object`||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var i=r.call(e,n||`default`);if(t(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(e)}function r(e){var r=n(e,`string`);return t(r)==`symbol`?r:r+``}function i(e,t,n){return(t=r(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const a=(e,t,n)=>{let r=Error(`API Error ${e} ${t}: ${n}`);return r.status=e,r.statusText=t,r.body=n,r};var o=class{constructor(e){i(this,`baseUrl`,void 0),i(this,`headers`,void 0),i(this,`timeout`,void 0),this.baseUrl=e.baseUrl.endsWith(`/`)?e.baseUrl:`${e.baseUrl}/`,this.headers={"Content-Type":`application/json`,Accept:`application/json`,...e.headers},this.timeout=e.timeout??3e4}async get(t,n){let r=this.buildUrl(t,n);return e(()=>this.request(r,{method:`GET`}))}async post(t,n,r){let i=this.buildUrl(t,r),a={method:`POST`,...n===void 0?{}:{body:JSON.stringify(n)}};return e(()=>this.request(i,a))}buildUrl(e,t){let n=new URL(e,this.baseUrl);if(t)for(let[e,r]of Object.entries(t))r!==void 0&&r!==``&&n.searchParams.set(e,r);return n.toString()}async request(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeout);try{let r=await fetch(e,{...t,headers:this.headers,signal:n.signal});if(!r.ok){let e=await r.text();throw a(r.status,r.statusText,e)}return await r.json()}catch(t){throw t instanceof Error&&`status`in t?t:t instanceof DOMException&&t.name===`AbortError`?Error(`Request to ${e} timed out after ${this.timeout}ms`,{cause:t}):t}finally{clearTimeout(r)}}};export{i as n,o as t};
2
+ //# sourceMappingURL=base.client-zZnUjoIb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.client-zZnUjoIb.js","names":[],"sources":["../src/clients/base.client.ts"],"sourcesContent":["import { withRetry } from \"../lib/retry\"\n\nexport type BaseClientOptions = {\n readonly baseUrl: string\n readonly headers?: Record<string, string>\n readonly timeout?: number\n}\n\ntype HttpError = Error & { status: number; statusText: string; body: string }\n\nconst createHttpError = (status: number, statusText: string, body: string): HttpError => {\n const error = new Error(`API Error ${status} ${statusText}: ${body}`) as HttpError\n error.status = status\n error.statusText = statusText\n error.body = body\n return error\n}\n\nexport class BaseClient {\n private readonly baseUrl: string\n private readonly headers: Record<string, string>\n private readonly timeout: number\n\n constructor(options: BaseClientOptions) {\n this.baseUrl = options.baseUrl.endsWith(\"/\") ? options.baseUrl : `${options.baseUrl}/`\n this.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n }\n this.timeout = options.timeout ?? 30000\n }\n\n async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = this.buildUrl(path, params)\n return withRetry(() => this.request<T>(url, { method: \"GET\" }))\n }\n\n async post<T>(path: string, body?: unknown, params?: Record<string, string>): Promise<T> {\n const url = this.buildUrl(path, params)\n const init: RequestInit = {\n method: \"POST\",\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n }\n return withRetry(() => this.request<T>(url, init))\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const url = new URL(path, this.baseUrl)\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== \"\") {\n url.searchParams.set(key, value)\n }\n }\n }\n return url.toString()\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.timeout)\n\n try {\n const response = await fetch(url, {\n ...init,\n headers: this.headers,\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw createHttpError(response.status, response.statusText, body)\n }\n\n return (await response.json()) as T\n } catch (error) {\n if (error instanceof Error && \"status\" in error) throw error\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new Error(`Request to ${url} timed out after ${this.timeout}ms`, { cause: error })\n }\n\n throw error\n } finally {\n clearTimeout(timeoutId)\n }\n }\n}\n"],"mappings":"+tBAUA,MAAM,GAAmB,EAAgB,EAAoB,IAA4B,CACvF,IAAM,EAAY,MAAM,aAAa,EAAO,GAAG,EAAW,IAAI,IAAO,CAIrE,MAHA,GAAM,OAAS,EACf,EAAM,WAAa,EACnB,EAAM,KAAO,EACN,GAGT,IAAa,EAAb,KAAwB,CAKtB,YAAY,EAA4B,QAJvB,UAAA,IAAA,GAAe,QACf,UAAA,IAAA,GAA+B,QAC/B,UAAA,IAAA,GAAe,CAG9B,KAAK,QAAU,EAAQ,QAAQ,SAAS,IAAI,CAAG,EAAQ,QAAU,GAAG,EAAQ,QAAQ,GACpF,KAAK,QAAU,CACb,eAAgB,mBAChB,OAAQ,mBACR,GAAG,EAAQ,QACZ,CACD,KAAK,QAAU,EAAQ,SAAW,IAGpC,MAAM,IAAO,EAAc,EAA6C,CACtE,IAAM,EAAM,KAAK,SAAS,EAAM,EAAO,CACvC,OAAO,MAAgB,KAAK,QAAW,EAAK,CAAE,OAAQ,MAAO,CAAC,CAAC,CAGjE,MAAM,KAAQ,EAAc,EAAgB,EAA6C,CACvF,IAAM,EAAM,KAAK,SAAS,EAAM,EAAO,CACjC,EAAoB,CACxB,OAAQ,OACR,GAAI,IAAS,IAAA,GAA6C,EAAE,CAAnC,CAAE,KAAM,KAAK,UAAU,EAAK,CAAE,CACxD,CACD,OAAO,MAAgB,KAAK,QAAW,EAAK,EAAK,CAAC,CAGpD,SAAiB,EAAc,EAAyC,CACtE,IAAM,EAAM,IAAI,IAAI,EAAM,KAAK,QAAQ,CACvC,GAAI,MACG,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAO,CAC3C,IAAU,IAAA,IAAa,IAAU,IACnC,EAAI,aAAa,IAAI,EAAK,EAAM,CAItC,OAAO,EAAI,UAAU,CAGvB,MAAc,QAAW,EAAa,EAA+B,CACnE,IAAM,EAAa,IAAI,gBACjB,EAAY,eAAiB,EAAW,OAAO,CAAE,KAAK,QAAQ,CAEpE,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,EAAK,CAChC,GAAG,EACH,QAAS,KAAK,QACd,OAAQ,EAAW,OACpB,CAAC,CAEF,GAAI,CAAC,EAAS,GAAI,CAChB,IAAM,EAAO,MAAM,EAAS,MAAM,CAClC,MAAM,EAAgB,EAAS,OAAQ,EAAS,WAAY,EAAK,CAGnE,OAAQ,MAAM,EAAS,MAAM,OACtB,EAAO,CAOd,MANI,aAAiB,OAAS,WAAY,EAAa,EAEnD,aAAiB,cAAgB,EAAM,OAAS,aACxC,MAAM,cAAc,EAAI,mBAAmB,KAAK,QAAQ,IAAK,CAAE,MAAO,EAAO,CAAC,CAGpF,SACE,CACR,aAAa,EAAU"}
@@ -0,0 +1,19 @@
1
+ //#region src/clients/base.client.d.ts
2
+ type BaseClientOptions = {
3
+ readonly baseUrl: string;
4
+ readonly headers?: Record<string, string>;
5
+ readonly timeout?: number;
6
+ };
7
+ declare class BaseClient {
8
+ private readonly baseUrl;
9
+ private readonly headers;
10
+ private readonly timeout;
11
+ constructor(options: BaseClientOptions);
12
+ get<T>(path: string, params?: Record<string, string>): Promise<T>;
13
+ post<T>(path: string, body?: unknown, params?: Record<string, string>): Promise<T>;
14
+ private buildUrl;
15
+ private request;
16
+ }
17
+ //#endregion
18
+ export { BaseClient, BaseClientOptions };
19
+ //# sourceMappingURL=base.client.d.ts.map
@@ -0,0 +1 @@
1
+ import{t as e}from"../base.client-zZnUjoIb.js";export{e as BaseClient};
@@ -0,0 +1,14 @@
1
+ //#region src/clients/bigquery.client.d.ts
2
+ type BigQueryResult = {
3
+ rows: Record<string, unknown>[];
4
+ totalRows: number;
5
+ estimatedBytesProcessed: string;
6
+ estimatedCostUsd: string;
7
+ };
8
+ declare const bigqueryPatentSearch: (query: string, fields?: string[], limit?: number) => Promise<BigQueryResult>;
9
+ declare const bigqueryPatentFamily: (familyId: string) => Promise<BigQueryResult>;
10
+ declare const bigqueryCitationNetwork: (publicationNumber: string, depth?: number) => Promise<BigQueryResult>;
11
+ declare const bigqueryCpcAnalytics: (cpcPrefix: string, dateFrom?: string, dateTo?: string) => Promise<BigQueryResult>;
12
+ //#endregion
13
+ export { bigqueryCitationNetwork, bigqueryCpcAnalytics, bigqueryPatentFamily, bigqueryPatentSearch };
14
+ //# sourceMappingURL=bigquery.client.d.ts.map
@@ -0,0 +1,66 @@
1
+ import{config as e}from"../lib/config.js";import{BigQuery as t}from"@google-cloud/bigquery";const n=`patents-public-data.patents.publications`,r=()=>new t({projectId:e.googleCloudProject}),i=e=>{let t=Number(e)/0xe8d4a51000;return t<=1?`Free (within 1 TB/month free tier)`:`~$${(t*5).toFixed(2)} (${t.toFixed(3)} TB at $5/TB)`},a=async(e,t)=>{let n=r(),[a]=await n.createQueryJob({query:e,params:t,dryRun:!0,useLegacySql:!1}),o=a.metadata?.statistics?.totalBytesProcessed??`0`,s=i(o),[c]=await n.createQueryJob({query:e,params:t,useLegacySql:!1}),[l]=await c.getQueryResults();return{rows:l,totalRows:l.length,estimatedBytesProcessed:o,estimatedCostUsd:s}},o=async(e,t=[`publication_number`,`title_localized`,`abstract_localized`,`publication_date`,`assignee_harmonized`],r=25)=>a(`
2
+ SELECT ${t.join(`, `)}
3
+ FROM \`${n}\`
4
+ WHERE SEARCH(abstract_localized.text, @query)
5
+ OR SEARCH(title_localized.text, @query)
6
+ ORDER BY publication_date DESC
7
+ LIMIT @limit
8
+ `,{query:e,limit:r}),s=async e=>a(`
9
+ SELECT
10
+ publication_number,
11
+ country_code,
12
+ title_localized,
13
+ publication_date,
14
+ grant_date,
15
+ application_number,
16
+ priority_date
17
+ FROM \`${n}\`
18
+ WHERE family_id = @familyId
19
+ ORDER BY publication_date
20
+ `,{familyId:e}),c=async(e,t=1)=>a(t===1?`
21
+ SELECT
22
+ p.publication_number AS source,
23
+ c.publication_number AS cited_publication,
24
+ c.category,
25
+ c.type
26
+ FROM \`${n}\` p,
27
+ UNNEST(citation) AS c
28
+ WHERE p.publication_number = @publicationNumber
29
+ `:`
30
+ WITH level1 AS (
31
+ SELECT
32
+ p.publication_number AS source,
33
+ c.publication_number AS cited
34
+ FROM \`${n}\` p,
35
+ UNNEST(citation) AS c
36
+ WHERE p.publication_number = @publicationNumber
37
+ ),
38
+ level2 AS (
39
+ SELECT
40
+ l1.cited AS source,
41
+ c.publication_number AS cited
42
+ FROM level1 l1
43
+ JOIN \`${n}\` p ON p.publication_number = l1.cited,
44
+ UNNEST(citation) AS c
45
+ )
46
+ SELECT * FROM level1
47
+ UNION ALL
48
+ SELECT * FROM level2
49
+ LIMIT 500
50
+ `,{publicationNumber:e}),l=async(e,t,r)=>{let i=`
51
+ SELECT
52
+ c.code AS cpc_code,
53
+ COUNT(*) AS patent_count,
54
+ COUNT(DISTINCT assignee.name) AS unique_assignees,
55
+ MIN(publication_date) AS earliest_publication,
56
+ MAX(publication_date) AS latest_publication
57
+ FROM \`${n}\` p,
58
+ UNNEST(cpc) AS c,
59
+ UNNEST(assignee_harmonized) AS assignee
60
+ WHERE c.code LIKE @cpcPrefix
61
+ ${[t?`AND publication_date >= @dateFrom`:``,r?`AND publication_date <= @dateTo`:``].join(` `)}
62
+ GROUP BY c.code
63
+ ORDER BY patent_count DESC
64
+ LIMIT 100
65
+ `,o={cpcPrefix:`${e}%`};return t&&(o.dateFrom=Number(t)),r&&(o.dateTo=Number(r)),a(i,o)};export{c as bigqueryCitationNetwork,l as bigqueryCpcAnalytics,s as bigqueryPatentFamily,o as bigqueryPatentSearch};
66
+ //# sourceMappingURL=bigquery.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bigquery.client.js","names":[],"sources":["../../src/clients/bigquery.client.ts"],"sourcesContent":["import { BigQuery } from \"@google-cloud/bigquery\"\n\nimport { config } from \"../lib/config\"\n\nconst DATASET = \"patents-public-data.patents.publications\"\n\ntype BigQueryResult = {\n rows: Record<string, unknown>[]\n totalRows: number\n estimatedBytesProcessed: string\n estimatedCostUsd: string\n}\n\nconst getBigQueryClient = (): BigQuery => {\n return new BigQuery({\n projectId: config.googleCloudProject,\n })\n}\n\nconst estimateCost = (bytes: string): string => {\n const tb = Number(bytes) / 1e12\n if (tb <= 1) return \"Free (within 1 TB/month free tier)\"\n return `~$${(tb * 5).toFixed(2)} (${tb.toFixed(3)} TB at $5/TB)`\n}\n\nconst runQuery = async (sql: string, params?: Record<string, unknown>): Promise<BigQueryResult> => {\n const client = getBigQueryClient()\n\n // Always dry run first to estimate cost\n const [dryRunJob] = await client.createQueryJob({\n query: sql,\n params,\n dryRun: true,\n useLegacySql: false,\n })\n\n const bytesProcessed = dryRunJob.metadata?.statistics?.totalBytesProcessed ?? \"0\"\n const costEstimate = estimateCost(bytesProcessed)\n\n // Execute the actual query\n const [job] = await client.createQueryJob({\n query: sql,\n params,\n useLegacySql: false,\n })\n\n const [rows] = await job.getQueryResults()\n\n return {\n rows: rows as Record<string, unknown>[],\n totalRows: rows.length,\n estimatedBytesProcessed: bytesProcessed,\n estimatedCostUsd: costEstimate,\n }\n}\n\nexport const bigqueryPatentSearch = async (\n query: string,\n fields: string[] = [\n \"publication_number\",\n \"title_localized\",\n \"abstract_localized\",\n \"publication_date\",\n \"assignee_harmonized\",\n ],\n limit = 25,\n): Promise<BigQueryResult> => {\n const selectedFields = fields.join(\", \")\n const sql = `\n SELECT ${selectedFields}\n FROM \\`${DATASET}\\`\n WHERE SEARCH(abstract_localized.text, @query)\n OR SEARCH(title_localized.text, @query)\n ORDER BY publication_date DESC\n LIMIT @limit\n `\n return runQuery(sql, { query, limit })\n}\n\nexport const bigqueryPatentFamily = async (familyId: string): Promise<BigQueryResult> => {\n const sql = `\n SELECT\n publication_number,\n country_code,\n title_localized,\n publication_date,\n grant_date,\n application_number,\n priority_date\n FROM \\`${DATASET}\\`\n WHERE family_id = @familyId\n ORDER BY publication_date\n `\n return runQuery(sql, { familyId })\n}\n\nexport const bigqueryCitationNetwork = async (publicationNumber: string, depth = 1): Promise<BigQueryResult> => {\n if (depth === 1) {\n const sql = `\n SELECT\n p.publication_number AS source,\n c.publication_number AS cited_publication,\n c.category,\n c.type\n FROM \\`${DATASET}\\` p,\n UNNEST(citation) AS c\n WHERE p.publication_number = @publicationNumber\n `\n return runQuery(sql, { publicationNumber })\n }\n\n // Depth 2: citations of citations\n const sql = `\n WITH level1 AS (\n SELECT\n p.publication_number AS source,\n c.publication_number AS cited\n FROM \\`${DATASET}\\` p,\n UNNEST(citation) AS c\n WHERE p.publication_number = @publicationNumber\n ),\n level2 AS (\n SELECT\n l1.cited AS source,\n c.publication_number AS cited\n FROM level1 l1\n JOIN \\`${DATASET}\\` p ON p.publication_number = l1.cited,\n UNNEST(citation) AS c\n )\n SELECT * FROM level1\n UNION ALL\n SELECT * FROM level2\n LIMIT 500\n `\n return runQuery(sql, { publicationNumber })\n}\n\nexport const bigqueryCpcAnalytics = async (\n cpcPrefix: string,\n dateFrom?: string,\n dateTo?: string,\n): Promise<BigQueryResult> => {\n const dateFilter = [\n dateFrom ? \"AND publication_date >= @dateFrom\" : \"\",\n dateTo ? \"AND publication_date <= @dateTo\" : \"\",\n ].join(\" \")\n\n const sql = `\n SELECT\n c.code AS cpc_code,\n COUNT(*) AS patent_count,\n COUNT(DISTINCT assignee.name) AS unique_assignees,\n MIN(publication_date) AS earliest_publication,\n MAX(publication_date) AS latest_publication\n FROM \\`${DATASET}\\` p,\n UNNEST(cpc) AS c,\n UNNEST(assignee_harmonized) AS assignee\n WHERE c.code LIKE @cpcPrefix\n ${dateFilter}\n GROUP BY c.code\n ORDER BY patent_count DESC\n LIMIT 100\n `\n\n const params: Record<string, unknown> = { cpcPrefix: `${cpcPrefix}%` }\n if (dateFrom) params.dateFrom = Number(dateFrom)\n if (dateTo) params.dateTo = Number(dateTo)\n\n return runQuery(sql, params)\n}\n"],"mappings":"4FAIA,MAAM,EAAU,2CASV,MACG,IAAI,EAAS,CAClB,UAAW,EAAO,mBACnB,CAAC,CAGE,EAAgB,GAA0B,CAC9C,IAAM,EAAK,OAAO,EAAM,CAAG,aAE3B,OADI,GAAM,EAAU,qCACb,MAAM,EAAK,GAAG,QAAQ,EAAE,CAAC,IAAI,EAAG,QAAQ,EAAE,CAAC,gBAG9C,EAAW,MAAO,EAAa,IAA8D,CACjG,IAAM,EAAS,GAAmB,CAG5B,CAAC,GAAa,MAAM,EAAO,eAAe,CAC9C,MAAO,EACP,SACA,OAAQ,GACR,aAAc,GACf,CAAC,CAEI,EAAiB,EAAU,UAAU,YAAY,qBAAuB,IACxE,EAAe,EAAa,EAAe,CAG3C,CAAC,GAAO,MAAM,EAAO,eAAe,CACxC,MAAO,EACP,SACA,aAAc,GACf,CAAC,CAEI,CAAC,GAAQ,MAAM,EAAI,iBAAiB,CAE1C,MAAO,CACC,OACN,UAAW,EAAK,OAChB,wBAAyB,EACzB,iBAAkB,EACnB,EAGU,EAAuB,MAClC,EACA,EAAmB,CACjB,qBACA,kBACA,qBACA,mBACA,sBACD,CACD,EAAQ,KAWD,EARK;aADW,EAAO,KAAK,KAAK,CAEd;aACf,EAAQ;;;;;IAME,CAAE,QAAO,QAAO,CAAC,CAG3B,EAAuB,KAAO,IAclC,EAbK;;;;;;;;;aASD,EAAQ;;;IAIE,CAAE,WAAU,CAAC,CAGvB,EAA0B,MAAO,EAA2B,EAAQ,IAYtE,EAXL,IAAU,EACA;;;;;;eAMD,EAAQ;;;MAQT;;;;;eAKC,EAAQ;;;;;;;;;eASR,EAAQ;;;;;;;IAlBE,CAAE,oBAAmB,CAAC,CA6BlC,EAAuB,MAClC,EACA,EACA,IAC4B,CAM5B,IAAM,EAAM;;;;;;;aAOD,EAAQ;;;;QAZA,CACjB,EAAW,oCAAsC,GACjD,EAAS,kCAAoC,GAC9C,CAAC,KAAK,IAAI,CAaM;;;;IAMX,EAAkC,CAAE,UAAW,GAAG,EAAU,GAAI,CAItE,OAHI,IAAU,EAAO,SAAW,OAAO,EAAS,EAC5C,IAAQ,EAAO,OAAS,OAAO,EAAO,EAEnC,EAAS,EAAK,EAAO"}
@@ -0,0 +1,13 @@
1
+ //#region src/clients/epo-ops.client.d.ts
2
+ type EpoNumberFormat = "docdb" | "epodoc" | "original";
3
+ declare const epoSearchPatents: (query: string, range?: string) => Promise<unknown>;
4
+ declare const epoGetBiblio: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
5
+ declare const epoGetAbstract: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
6
+ declare const epoGetClaims: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
7
+ declare const epoGetDescription: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
8
+ declare const epoFamilyLookup: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
9
+ declare const epoLegalStatus: (number: string, format?: EpoNumberFormat) => Promise<unknown>;
10
+ declare const epoNumberConvert: (number: string, inputFormat: EpoNumberFormat, outputFormat: EpoNumberFormat) => Promise<unknown>;
11
+ //#endregion
12
+ export { epoFamilyLookup, epoGetAbstract, epoGetBiblio, epoGetClaims, epoGetDescription, epoLegalStatus, epoNumberConvert, epoSearchPatents };
13
+ //# sourceMappingURL=epo-ops.client.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{config as e}from"../lib/config.js";import{withRetry as t}from"../lib/retry.js";import{XMLParser as n}from"fast-xml-parser";let r;const i=new n({ignoreAttributes:!1,attributeNamePrefix:`@_`,removeNSPrefix:!0,isArray:e=>[`exchange-document`,`document-id`,`classification-ipcr`,`classification-cpc`,`patent-classification`,`applicant`,`inventor`,`priority-claim`,`family-member`,`legal`].includes(e)}),a=async()=>{if(r&&Date.now()<r.expiresAt)return r.token;let t=e.epoConsumerKey,n=e.epoConsumerSecret;if(!t||!n)throw Error(`EPO OPS credentials not configured. Set EPO_CONSUMER_KEY and EPO_CONSUMER_SECRET.`);let i=Buffer.from(`${t}:${n}`).toString(`base64`),a=await fetch(`https://ops.epo.org/3.2/auth/accesstoken`,{method:`POST`,headers:{Authorization:`Basic ${i}`,"Content-Type":`application/x-www-form-urlencoded`},body:`grant_type=client_credentials`});if(!a.ok)throw Error(`EPO OAuth failed: ${a.status} ${a.statusText}`);return r={token:(await a.json()).access_token,expiresAt:Date.now()+1140*1e3},r.token},o=()=>{r=void 0},s=async(n,r=`application/xml`)=>t(async()=>{let t=await a(),s=new AbortController,c=setTimeout(()=>s.abort(),e.requestTimeout);try{let e=await fetch(`https://ops.epo.org/3.2/rest-services/${n}`,{headers:{Authorization:`Bearer ${t}`,Accept:r},signal:s.signal});if(e.status===400||e.status===401)throw o(),Error(`EPO auth error: ${e.status}`);if(!e.ok){let t=await e.text();throw Error(`EPO API error ${e.status}: ${t.slice(0,500)}`)}if(e.headers.get(`x-throttling-control`)?.includes(`black`))throw Error(`EPO rate limit exceeded (black). Wait before retrying.`);if(r===`application/json`)return await e.json();let a=await e.text();return i.parse(a)}finally{clearTimeout(c)}},{maxRetries:e.maxRetries,minWait:e.retryMinWait,maxWait:e.retryMaxWait}),c=(e,t=`docdb`)=>{let n=e.replace(/\s+/g,``).replace(/[/,]/g,``);switch(t){case`docdb`:return n;case`epodoc`:return n;case`original`:return e;default:return n}},l=async(e,t)=>{let n=t?`&Range=${t}`:``;return s(`published-data/search?q=${encodeURIComponent(e)}${n}`)},u=async(e,t=`docdb`)=>s(`published-data/publication/${t}/${c(e,t)}/biblio`),d=async(e,t=`docdb`)=>s(`published-data/publication/${t}/${c(e,t)}/abstract`),f=async(e,t=`docdb`)=>s(`published-data/publication/${t}/${c(e,t)}/claims`),p=async(e,t=`docdb`)=>s(`published-data/publication/${t}/${c(e,t)}/description`),m=async(e,t=`docdb`)=>s(`family/publication/${t}/${c(e,t)}`),h=async(e,t=`docdb`)=>s(`published-data/publication/${t}/${c(e,t)}/legal`),g=async(e,t,n)=>s(`number-service/${t}/${c(e,t)}/${n}`);export{m as epoFamilyLookup,d as epoGetAbstract,u as epoGetBiblio,f as epoGetClaims,p as epoGetDescription,h as epoLegalStatus,g as epoNumberConvert,l as epoSearchPatents};
2
+ //# sourceMappingURL=epo-ops.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epo-ops.client.js","names":[],"sources":["../../src/clients/epo-ops.client.ts"],"sourcesContent":["import { XMLParser } from \"fast-xml-parser\"\n\nimport { config } from \"../lib/config\"\nimport { withRetry } from \"../lib/retry\"\nimport { BaseClient } from \"./base.client\"\n\nconst EPO_AUTH_URL = \"https://ops.epo.org/3.2/auth/accesstoken\"\nconst EPO_BASE_URL = \"https://ops.epo.org/3.2/rest-services/\"\n\ntype EpoNumberFormat = \"docdb\" | \"epodoc\" | \"original\"\n\ntype TokenCache = {\n token: string\n expiresAt: number\n}\n\nlet tokenCache: TokenCache | undefined\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n removeNSPrefix: true,\n isArray: (name) => {\n const arrayElements = [\n \"exchange-document\",\n \"document-id\",\n \"classification-ipcr\",\n \"classification-cpc\",\n \"patent-classification\",\n \"applicant\",\n \"inventor\",\n \"priority-claim\",\n \"family-member\",\n \"legal\",\n ]\n return arrayElements.includes(name)\n },\n})\n\nconst getAccessToken = async (): Promise<string> => {\n if (tokenCache && Date.now() < tokenCache.expiresAt) {\n return tokenCache.token\n }\n\n const key = config.epoConsumerKey\n const secret = config.epoConsumerSecret\n\n if (!key || !secret) {\n throw new Error(\"EPO OPS credentials not configured. Set EPO_CONSUMER_KEY and EPO_CONSUMER_SECRET.\")\n }\n\n const credentials = Buffer.from(`${key}:${secret}`).toString(\"base64\")\n\n const response = await fetch(EPO_AUTH_URL, {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${credentials}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: \"grant_type=client_credentials\",\n })\n\n if (!response.ok) {\n throw new Error(`EPO OAuth failed: ${response.status} ${response.statusText}`)\n }\n\n const data = (await response.json()) as { access_token: string }\n tokenCache = {\n token: data.access_token,\n expiresAt: Date.now() + 19 * 60 * 1000, // 19 min (1 min buffer before 20 min expiry)\n }\n\n return tokenCache.token\n}\n\nconst clearTokenCache = (): void => {\n tokenCache = undefined\n}\n\nconst epoRequest = async <T>(path: string, accept = \"application/xml\"): Promise<T> => {\n const makeRequest = async (): Promise<T> => {\n const token = await getAccessToken()\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), config.requestTimeout)\n\n try {\n const response = await fetch(`${EPO_BASE_URL}${path}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: accept,\n },\n signal: controller.signal,\n })\n\n if (response.status === 400 || response.status === 401) {\n clearTokenCache()\n throw new Error(`EPO auth error: ${response.status}`)\n }\n\n if (!response.ok) {\n const text = await response.text()\n throw new Error(`EPO API error ${response.status}: ${text.slice(0, 500)}`)\n }\n\n const throttling = response.headers.get(\"x-throttling-control\")\n if (throttling?.includes(\"black\")) {\n throw new Error(\"EPO rate limit exceeded (black). Wait before retrying.\")\n }\n\n if (accept === \"application/json\") {\n return (await response.json()) as T\n }\n\n const xml = await response.text()\n return xmlParser.parse(xml) as T\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n return withRetry(makeRequest, {\n maxRetries: config.maxRetries,\n minWait: config.retryMinWait,\n maxWait: config.retryMaxWait,\n })\n}\n\nconst formatNumber = (number: string, format: EpoNumberFormat = \"docdb\"): string => {\n const cleaned = number.replace(/\\s+/g, \"\").replace(/[/,]/g, \"\")\n switch (format) {\n case \"docdb\":\n return cleaned\n case \"epodoc\":\n return cleaned\n case \"original\":\n return number\n default:\n return cleaned\n }\n}\n\nexport const epoSearchPatents = async (query: string, range?: string): Promise<unknown> => {\n const rangePart = range ? `&Range=${range}` : \"\"\n return epoRequest(`published-data/search?q=${encodeURIComponent(query)}${rangePart}`)\n}\n\nexport const epoGetBiblio = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`published-data/publication/${format}/${num}/biblio`)\n}\n\nexport const epoGetAbstract = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`published-data/publication/${format}/${num}/abstract`)\n}\n\nexport const epoGetClaims = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`published-data/publication/${format}/${num}/claims`)\n}\n\nexport const epoGetDescription = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`published-data/publication/${format}/${num}/description`)\n}\n\nexport const epoFamilyLookup = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`family/publication/${format}/${num}`)\n}\n\nexport const epoLegalStatus = async (number: string, format: EpoNumberFormat = \"docdb\"): Promise<unknown> => {\n const num = formatNumber(number, format)\n return epoRequest(`published-data/publication/${format}/${num}/legal`)\n}\n\nexport const epoNumberConvert = async (\n number: string,\n inputFormat: EpoNumberFormat,\n outputFormat: EpoNumberFormat,\n): Promise<unknown> => {\n const num = formatNumber(number, inputFormat)\n return epoRequest(`number-service/${inputFormat}/${num}/${outputFormat}`)\n}\n"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ //#region src/clients/odp.client.d.ts
2
+ type OdpConfig = {
3
+ readonly apiKey: string;
4
+ readonly baseUrl?: string;
5
+ readonly timeout?: number;
6
+ };
7
+ declare const getOdpConfig: () => OdpConfig;
8
+ declare class OdpClient {
9
+ private readonly client;
10
+ constructor(config?: OdpConfig);
11
+ searchApplications(query: string, limit?: number, offset?: number, sort?: string): Promise<unknown>;
12
+ getApplication(appNum: string): Promise<unknown>;
13
+ getApplicationMetadata(appNum: string): Promise<unknown>;
14
+ getContinuity(appNum: string): Promise<unknown>;
15
+ getAssignment(appNum: string): Promise<unknown>;
16
+ getAdjustment(appNum: string): Promise<unknown>;
17
+ getAttorney(appNum: string): Promise<unknown>;
18
+ getForeignPriority(appNum: string): Promise<unknown>;
19
+ getTransactions(appNum: string): Promise<unknown>;
20
+ getDocuments(appNum: string): Promise<unknown>;
21
+ searchDatasets(query: string): Promise<unknown>;
22
+ getDataset(productId: string): Promise<unknown>;
23
+ searchProceedings(query: string, type?: string, limit?: number): Promise<unknown>;
24
+ getProceeding(trialNumber: string): Promise<unknown>;
25
+ getProceedingDocuments(trialNumber: string): Promise<unknown>;
26
+ searchDecisions(query: string, limit?: number): Promise<unknown>;
27
+ getDecision(decisionId: string): Promise<unknown>;
28
+ searchAppeals(query: string, limit?: number): Promise<unknown>;
29
+ getAppeal(appealId: string): Promise<unknown>;
30
+ getEnrichedCitations(patentNumber: string): Promise<unknown>;
31
+ searchCitations(query: string, limit?: number): Promise<unknown>;
32
+ getCitationMetrics(patentNumber: string): Promise<unknown>;
33
+ searchLitigation(params: {
34
+ query?: string;
35
+ plaintiff?: string;
36
+ defendant?: string;
37
+ patent_number?: string;
38
+ court?: string;
39
+ date_from?: string;
40
+ date_to?: string;
41
+ limit?: number;
42
+ }): Promise<unknown>;
43
+ getLitigationCase(caseId: string): Promise<unknown>;
44
+ getLitigationByPatent(patentNumber: string): Promise<unknown>;
45
+ getOfficeActionText(applicationNumber: string): Promise<unknown>;
46
+ searchOfficeActions(query: string, limit?: number): Promise<unknown>;
47
+ getOfficeActionCitations(applicationNumber: string): Promise<unknown>;
48
+ getOfficeActionRejections(applicationNumber: string): Promise<unknown>;
49
+ }
50
+ //#endregion
51
+ export { OdpClient, OdpConfig, getOdpConfig };
52
+ //# sourceMappingURL=odp.client.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{normalizePatentNumber as e}from"../lib/patent-number.js";import{n as t,t as n}from"../base.client-zZnUjoIb.js";const r=()=>{let e=process.env.USPTO_API_KEY;if(!e)throw Error(`USPTO_API_KEY environment variable is required for ODP client`);return{apiKey:e,baseUrl:process.env.USPTO_BASE_URL??`https://api.uspto.gov/api/v1/`,timeout:process.env.USPTO_TIMEOUT?parseInt(process.env.USPTO_TIMEOUT,10):3e4}};var i=class{constructor(e){t(this,`client`,void 0);let i=e??r();this.client=new n({baseUrl:i.baseUrl??`https://api.uspto.gov/api/v1/`,headers:{"X-API-KEY":i.apiKey},timeout:i.timeout})}async searchApplications(e,t,n,r){let i={searchText:e};return t!==void 0&&(i.limit=String(t)),n!==void 0&&(i.offset=String(n)),r!==void 0&&(i.sort=r),this.client.get(`patent/applications`,i)}async getApplication(t){return this.client.get(`patent/applications/${e(t)}`)}async getApplicationMetadata(t){return this.client.get(`patent/applications/${e(t)}/metadata`)}async getContinuity(t){return this.client.get(`patent/applications/${e(t)}/continuity`)}async getAssignment(t){return this.client.get(`patent/applications/${e(t)}/assignment`)}async getAdjustment(t){return this.client.get(`patent/applications/${e(t)}/adjustment`)}async getAttorney(t){return this.client.get(`patent/applications/${e(t)}/attorney`)}async getForeignPriority(t){return this.client.get(`patent/applications/${e(t)}/foreign-priority`)}async getTransactions(t){return this.client.get(`patent/applications/${e(t)}/transactions`)}async getDocuments(t){return this.client.get(`patent/applications/${e(t)}/documents`)}async searchDatasets(e){return this.client.get(`datasets`,{searchText:e})}async getDataset(e){return this.client.get(`datasets/${e}`)}async searchProceedings(e,t,n){let r={searchText:e};return t!==void 0&&(r.type=t),n!==void 0&&(r.limit=String(n)),this.client.get(`patent/trials`,r)}async getProceeding(e){return this.client.get(`patent/trials/${e}`)}async getProceedingDocuments(e){return this.client.get(`patent/trials/${e}/documents`)}async searchDecisions(e,t){let n={searchText:e};return t!==void 0&&(n.limit=String(t)),this.client.get(`patent/trials/decisions`,n)}async getDecision(e){return this.client.get(`patent/trials/decisions/${e}`)}async searchAppeals(e,t){let n={searchText:e};return t!==void 0&&(n.limit=String(t)),this.client.get(`patent/appeals`,n)}async getAppeal(e){return this.client.get(`patent/appeals/${e}`)}async getEnrichedCitations(t){return this.client.get(`patent/citations/${e(t)}`)}async searchCitations(e,t){let n={searchText:e};return t!==void 0&&(n.limit=String(t)),this.client.get(`patent/citations`,n)}async getCitationMetrics(t){return this.client.get(`patent/citations/${e(t)}/metrics`)}async searchLitigation(t){let n={};return t.query!==void 0&&(n.searchText=t.query),t.plaintiff!==void 0&&(n.plaintiff=t.plaintiff),t.defendant!==void 0&&(n.defendant=t.defendant),t.patent_number!==void 0&&(n.patentNumber=e(t.patent_number)),t.court!==void 0&&(n.court=t.court),t.date_from!==void 0&&(n.dateFrom=t.date_from),t.date_to!==void 0&&(n.dateTo=t.date_to),t.limit!==void 0&&(n.limit=String(t.limit)),this.client.get(`patent/litigation`,n)}async getLitigationCase(e){return this.client.get(`patent/litigation/${e}`)}async getLitigationByPatent(t){return this.client.get(`patent/litigation/patent/${e(t)}`)}async getOfficeActionText(t){return this.client.get(`patent/office-actions/${e(t)}/text`)}async searchOfficeActions(e,t){let n={searchText:e};return t!==void 0&&(n.limit=String(t)),this.client.get(`patent/office-actions`,n)}async getOfficeActionCitations(t){return this.client.get(`patent/office-actions/${e(t)}/citations`)}async getOfficeActionRejections(t){return this.client.get(`patent/office-actions/${e(t)}/rejections`)}};export{i as OdpClient,r as getOdpConfig};
2
+ //# sourceMappingURL=odp.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"odp.client.js","names":[],"sources":["../../src/clients/odp.client.ts"],"sourcesContent":["import { normalizePatentNumber } from \"../lib/patent-number\"\nimport { BaseClient } from \"./base.client\"\n\nexport type OdpConfig = {\n readonly apiKey: string\n readonly baseUrl?: string\n readonly timeout?: number\n}\n\nexport const getOdpConfig = (): OdpConfig => {\n const apiKey = process.env.USPTO_API_KEY\n if (!apiKey) {\n throw new Error(\"USPTO_API_KEY environment variable is required for ODP client\")\n }\n return {\n apiKey,\n baseUrl: process.env.USPTO_BASE_URL ?? \"https://api.uspto.gov/api/v1/\",\n timeout: process.env.USPTO_TIMEOUT ? parseInt(process.env.USPTO_TIMEOUT, 10) : 30000,\n }\n}\n\nexport class OdpClient {\n private readonly client: BaseClient\n\n constructor(config?: OdpConfig) {\n const cfg = config ?? getOdpConfig()\n this.client = new BaseClient({\n baseUrl: cfg.baseUrl ?? \"https://api.uspto.gov/api/v1/\",\n headers: {\n \"X-API-KEY\": cfg.apiKey,\n },\n timeout: cfg.timeout,\n })\n }\n\n // ── Application Methods ──────────────────────────────────────────────\n\n async searchApplications(query: string, limit?: number, offset?: number, sort?: string): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (limit !== undefined) params.limit = String(limit)\n if (offset !== undefined) params.offset = String(offset)\n if (sort !== undefined) params.sort = sort\n return this.client.get(\"patent/applications\", params)\n }\n\n async getApplication(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}`)\n }\n\n async getApplicationMetadata(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/metadata`)\n }\n\n async getContinuity(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/continuity`)\n }\n\n async getAssignment(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/assignment`)\n }\n\n async getAdjustment(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/adjustment`)\n }\n\n async getAttorney(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/attorney`)\n }\n\n async getForeignPriority(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/foreign-priority`)\n }\n\n async getTransactions(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/transactions`)\n }\n\n async getDocuments(appNum: string): Promise<unknown> {\n return this.client.get(`patent/applications/${normalizePatentNumber(appNum)}/documents`)\n }\n\n // ── Dataset Methods ──────────────────────────────────────────────────\n\n async searchDatasets(query: string): Promise<unknown> {\n return this.client.get(\"datasets\", { searchText: query })\n }\n\n async getDataset(productId: string): Promise<unknown> {\n return this.client.get(`datasets/${productId}`)\n }\n\n // ── PTAB Methods ─────────────────────────────────────────────────────\n\n async searchProceedings(query: string, type?: string, limit?: number): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (type !== undefined) params.type = type\n if (limit !== undefined) params.limit = String(limit)\n return this.client.get(\"patent/trials\", params)\n }\n\n async getProceeding(trialNumber: string): Promise<unknown> {\n return this.client.get(`patent/trials/${trialNumber}`)\n }\n\n async getProceedingDocuments(trialNumber: string): Promise<unknown> {\n return this.client.get(`patent/trials/${trialNumber}/documents`)\n }\n\n async searchDecisions(query: string, limit?: number): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (limit !== undefined) params.limit = String(limit)\n return this.client.get(\"patent/trials/decisions\", params)\n }\n\n async getDecision(decisionId: string): Promise<unknown> {\n return this.client.get(`patent/trials/decisions/${decisionId}`)\n }\n\n async searchAppeals(query: string, limit?: number): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (limit !== undefined) params.limit = String(limit)\n return this.client.get(\"patent/appeals\", params)\n }\n\n async getAppeal(appealId: string): Promise<unknown> {\n return this.client.get(`patent/appeals/${appealId}`)\n }\n\n // ── Citation / Litigation Methods ────────────────────────────────────\n\n async getEnrichedCitations(patentNumber: string): Promise<unknown> {\n return this.client.get(`patent/citations/${normalizePatentNumber(patentNumber)}`)\n }\n\n async searchCitations(query: string, limit?: number): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (limit !== undefined) params.limit = String(limit)\n return this.client.get(\"patent/citations\", params)\n }\n\n async getCitationMetrics(patentNumber: string): Promise<unknown> {\n return this.client.get(`patent/citations/${normalizePatentNumber(patentNumber)}/metrics`)\n }\n\n async searchLitigation(params: {\n query?: string\n plaintiff?: string\n defendant?: string\n patent_number?: string\n court?: string\n date_from?: string\n date_to?: string\n limit?: number\n }): Promise<unknown> {\n const searchParams: Record<string, string> = {}\n if (params.query !== undefined) searchParams.searchText = params.query\n if (params.plaintiff !== undefined) searchParams.plaintiff = params.plaintiff\n if (params.defendant !== undefined) searchParams.defendant = params.defendant\n if (params.patent_number !== undefined) searchParams.patentNumber = normalizePatentNumber(params.patent_number)\n if (params.court !== undefined) searchParams.court = params.court\n if (params.date_from !== undefined) searchParams.dateFrom = params.date_from\n if (params.date_to !== undefined) searchParams.dateTo = params.date_to\n if (params.limit !== undefined) searchParams.limit = String(params.limit)\n return this.client.get(\"patent/litigation\", searchParams)\n }\n\n async getLitigationCase(caseId: string): Promise<unknown> {\n return this.client.get(`patent/litigation/${caseId}`)\n }\n\n async getLitigationByPatent(patentNumber: string): Promise<unknown> {\n return this.client.get(`patent/litigation/patent/${normalizePatentNumber(patentNumber)}`)\n }\n\n // ── Office Action Methods ───────────────────────────────────────────\n\n async getOfficeActionText(applicationNumber: string): Promise<unknown> {\n return this.client.get(`patent/office-actions/${normalizePatentNumber(applicationNumber)}/text`)\n }\n\n async searchOfficeActions(query: string, limit?: number): Promise<unknown> {\n const params: Record<string, string> = { searchText: query }\n if (limit !== undefined) params.limit = String(limit)\n return this.client.get(\"patent/office-actions\", params)\n }\n\n async getOfficeActionCitations(applicationNumber: string): Promise<unknown> {\n return this.client.get(`patent/office-actions/${normalizePatentNumber(applicationNumber)}/citations`)\n }\n\n async getOfficeActionRejections(applicationNumber: string): Promise<unknown> {\n return this.client.get(`patent/office-actions/${normalizePatentNumber(applicationNumber)}/rejections`)\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { zAssigneeSuccessResponse, zAttorneySuccessResponse, zCpcSubclassSuccessResponse, zGClaimSuccessResponse, zInventorSuccessResponse, zIpcClassificationSuccessResponse, zPatentSuccessResponse } from "../generated/patentsview/zod.gen.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/clients/patentsview.client.d.ts
5
+ type PatentsViewClientOptions = {
6
+ readonly baseUrl?: string;
7
+ readonly apiKey?: string;
8
+ readonly timeout?: number;
9
+ };
10
+ type PatentResponse = z.infer<typeof zPatentSuccessResponse>;
11
+ type AssigneeResponse = z.infer<typeof zAssigneeSuccessResponse>;
12
+ type InventorResponse = z.infer<typeof zInventorSuccessResponse>;
13
+ type AttorneyResponse = z.infer<typeof zAttorneySuccessResponse>;
14
+ type ClaimResponse = z.infer<typeof zGClaimSuccessResponse>;
15
+ type CpcSubclassResponse = z.infer<typeof zCpcSubclassSuccessResponse>;
16
+ type IpcResponse = z.infer<typeof zIpcClassificationSuccessResponse>;
17
+ declare class PatentsViewClient {
18
+ private readonly client;
19
+ constructor(options?: PatentsViewClientOptions);
20
+ searchPatents(query: string, searchType?: "text" | "assignee" | "inventor", limit?: number): Promise<PatentResponse>;
21
+ getPatent(patentId: string): Promise<PatentResponse>;
22
+ searchAssignees(name: string, limit?: number): Promise<AssigneeResponse>;
23
+ getAssignee(id: string): Promise<AssigneeResponse>;
24
+ searchInventors(name: string, limit?: number): Promise<InventorResponse>;
25
+ getInventor(id: string): Promise<InventorResponse>;
26
+ searchAttorneys(name: string, limit?: number): Promise<AttorneyResponse>;
27
+ getAttorney(id: string): Promise<AttorneyResponse>;
28
+ getClaims(patentId: string): Promise<ClaimResponse>;
29
+ getDescription(patentId: string): Promise<PatentResponse>;
30
+ searchByCpc(cpcCode: string, limit?: number): Promise<PatentResponse>;
31
+ lookupCpc(cpcCode: string): Promise<CpcSubclassResponse>;
32
+ searchByIpc(ipcCode: string, limit?: number): Promise<PatentResponse>;
33
+ lookupIpc(ipcCode: string): Promise<IpcResponse>;
34
+ private buildPatentQuery;
35
+ }
36
+ //#endregion
37
+ export { AssigneeResponse, AttorneyResponse, ClaimResponse, CpcSubclassResponse, InventorResponse, IpcResponse, PatentResponse, PatentsViewClient, PatentsViewClientOptions };
38
+ //# sourceMappingURL=patentsview.client.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{n as e,t}from"../base.client-zZnUjoIb.js";import{zAssigneeSuccessResponse as n,zAttorneySuccessResponse as r,zCpcSubclassSuccessResponse as i,zGClaimSuccessResponse as a,zInventorSuccessResponse as o,zIpcClassificationSuccessResponse as s,zPatentSuccessResponse as c}from"../generated/patentsview/zod.gen.js";const l=(e,t)=>{let n=e.safeParse(t);return n.success?n.data:t},u=[`patent_id`,`patent_title`,`patent_abstract`,`patent_date`,`patent_type`,`assignees`,`inventors`],d=(e,t,n)=>{let r={q:JSON.stringify(e)};return t&&(r.f=JSON.stringify(t)),n&&(r.o=JSON.stringify(n)),r};var f=class{constructor(n){e(this,`client`,void 0);let r=n?.baseUrl??`https://search.patentsview.org/api/v1/`,i={};n?.apiKey&&(i[`X-Api-Key`]=n.apiKey),this.client=new t({baseUrl:r,headers:i,timeout:n?.timeout})}async searchPatents(e,t=`text`,n=25){let r=d(this.buildPatentQuery(e,t),[...u],{size:n});return l(c,await this.client.get(`patent/`,r))}async getPatent(e){return l(c,await this.client.get(`patent/${e}/`))}async searchAssignees(e,t=25){let r=d({_text_any:{assignee_organization:e}},void 0,{size:t});return l(n,await this.client.get(`assignee/`,r))}async getAssignee(e){return l(n,await this.client.get(`assignee/${e}/`))}async searchInventors(e,t=25){let n=d({_or:[{_text_any:{inventor_name_first:e}},{_text_any:{inventor_name_last:e}}]},void 0,{size:t});return l(o,await this.client.get(`inventor/`,n))}async getInventor(e){return l(o,await this.client.get(`inventor/${e}/`))}async searchAttorneys(e,t=25){let n=d({_or:[{_text_any:{attorney_organization:e}},{_text_any:{attorney_name_last:e}}]},void 0,{size:t});return l(r,await this.client.get(`patent/attorney/`,n))}async getAttorney(e){return l(r,await this.client.get(`patent/attorney/${e}/`))}async getClaims(e){let t=d({_eq:{patent_id:e}});return l(a,await this.client.get(`g_claim/`,t))}async getDescription(e){let t={f:JSON.stringify([`patent_id`,`patent_title`,`patent_abstract`])};return l(c,await this.client.get(`patent/${e}/`,t))}async searchByCpc(e,t=25){let n=d({_eq:{cpc_subgroup_id:e}},[...u],{size:t});return l(c,await this.client.get(`patent/`,n))}async lookupCpc(e){let t=d({_eq:{cpc_subclass_id:e}});return l(i,await this.client.get(`cpc_subclass/`,t))}async searchByIpc(e,t=25){let n=d({_eq:{ipc_class:e}},[...u],{size:t});return l(c,await this.client.get(`patent/`,n))}async lookupIpc(e){let t=d({_eq:{ipc_class:e}});return l(s,await this.client.get(`ipc/`,t))}buildPatentQuery(e,t){switch(t){case`text`:return{_text_any:{patent_abstract:e}};case`assignee`:return{_text_any:{assignee_organization:e}};case`inventor`:return{_or:[{_text_any:{inventor_name_first:e}},{_text_any:{inventor_name_last:e}}]}}}};export{f as PatentsViewClient};
2
+ //# sourceMappingURL=patentsview.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patentsview.client.js","names":[],"sources":["../../src/clients/patentsview.client.ts"],"sourcesContent":["import type { z, ZodType } from \"zod\"\n\nimport {\n zAssigneeSuccessResponse,\n zAttorneySuccessResponse,\n zCpcSubclassSuccessResponse,\n zGClaimSuccessResponse,\n zInventorSuccessResponse,\n zIpcClassificationSuccessResponse,\n zPatentSuccessResponse,\n} from \"../generated/patentsview/zod.gen\"\nimport { BaseClient } from \"./base.client\"\n\nconst looseParse = <T extends ZodType>(schema: T, data: unknown): z.infer<T> => {\n const result = schema.safeParse(data)\n return result.success ? result.data : (data as z.infer<T>)\n}\n\nexport type PatentsViewClientOptions = {\n readonly baseUrl?: string\n readonly apiKey?: string\n readonly timeout?: number\n}\n\nexport type PatentResponse = z.infer<typeof zPatentSuccessResponse>\nexport type AssigneeResponse = z.infer<typeof zAssigneeSuccessResponse>\nexport type InventorResponse = z.infer<typeof zInventorSuccessResponse>\nexport type AttorneyResponse = z.infer<typeof zAttorneySuccessResponse>\nexport type ClaimResponse = z.infer<typeof zGClaimSuccessResponse>\nexport type CpcSubclassResponse = z.infer<typeof zCpcSubclassSuccessResponse>\nexport type IpcResponse = z.infer<typeof zIpcClassificationSuccessResponse>\n\nconst DEFAULT_PATENT_FIELDS = [\n \"patent_id\",\n \"patent_title\",\n \"patent_abstract\",\n \"patent_date\",\n \"patent_type\",\n \"assignees\",\n \"inventors\",\n] as const\n\nconst buildParams = (\n q: Record<string, unknown>,\n f?: ReadonlyArray<string>,\n o?: Record<string, unknown>,\n): Record<string, string> => {\n const params: Record<string, string> = { q: JSON.stringify(q) }\n if (f) params.f = JSON.stringify(f)\n if (o) params.o = JSON.stringify(o)\n return params\n}\n\nexport class PatentsViewClient {\n private readonly client: BaseClient\n\n constructor(options?: PatentsViewClientOptions) {\n const baseUrl = options?.baseUrl ?? \"https://search.patentsview.org/api/v1/\"\n const headers: Record<string, string> = {}\n if (options?.apiKey) {\n headers[\"X-Api-Key\"] = options.apiKey\n }\n\n this.client = new BaseClient({\n baseUrl,\n headers,\n timeout: options?.timeout,\n })\n }\n\n async searchPatents(\n query: string,\n searchType: \"text\" | \"assignee\" | \"inventor\" = \"text\",\n limit = 25,\n ): Promise<PatentResponse> {\n const q = this.buildPatentQuery(query, searchType)\n const params = buildParams(q, [...DEFAULT_PATENT_FIELDS], { size: limit })\n const raw = await this.client.get<unknown>(\"patent/\", params)\n return looseParse(zPatentSuccessResponse, raw)\n }\n\n async getPatent(patentId: string): Promise<PatentResponse> {\n const raw = await this.client.get<unknown>(`patent/${patentId}/`)\n return looseParse(zPatentSuccessResponse, raw)\n }\n\n async searchAssignees(name: string, limit = 25): Promise<AssigneeResponse> {\n const params = buildParams({ _text_any: { assignee_organization: name } }, undefined, { size: limit })\n const raw = await this.client.get<unknown>(\"assignee/\", params)\n return looseParse(zAssigneeSuccessResponse, raw)\n }\n\n async getAssignee(id: string): Promise<AssigneeResponse> {\n const raw = await this.client.get<unknown>(`assignee/${id}/`)\n return looseParse(zAssigneeSuccessResponse, raw)\n }\n\n async searchInventors(name: string, limit = 25): Promise<InventorResponse> {\n const q = {\n _or: [{ _text_any: { inventor_name_first: name } }, { _text_any: { inventor_name_last: name } }],\n }\n const params = buildParams(q, undefined, { size: limit })\n const raw = await this.client.get<unknown>(\"inventor/\", params)\n return looseParse(zInventorSuccessResponse, raw)\n }\n\n async getInventor(id: string): Promise<InventorResponse> {\n const raw = await this.client.get<unknown>(`inventor/${id}/`)\n return looseParse(zInventorSuccessResponse, raw)\n }\n\n async searchAttorneys(name: string, limit = 25): Promise<AttorneyResponse> {\n const q = {\n _or: [{ _text_any: { attorney_organization: name } }, { _text_any: { attorney_name_last: name } }],\n }\n const params = buildParams(q, undefined, { size: limit })\n const raw = await this.client.get<unknown>(\"patent/attorney/\", params)\n return looseParse(zAttorneySuccessResponse, raw)\n }\n\n async getAttorney(id: string): Promise<AttorneyResponse> {\n const raw = await this.client.get<unknown>(`patent/attorney/${id}/`)\n return looseParse(zAttorneySuccessResponse, raw)\n }\n\n async getClaims(patentId: string): Promise<ClaimResponse> {\n const params = buildParams({ _eq: { patent_id: patentId } })\n const raw = await this.client.get<unknown>(\"g_claim/\", params)\n return looseParse(zGClaimSuccessResponse, raw)\n }\n\n async getDescription(patentId: string): Promise<PatentResponse> {\n const params: Record<string, string> = {\n f: JSON.stringify([\"patent_id\", \"patent_title\", \"patent_abstract\"]),\n }\n const raw = await this.client.get<unknown>(`patent/${patentId}/`, params)\n return looseParse(zPatentSuccessResponse, raw)\n }\n\n async searchByCpc(cpcCode: string, limit = 25): Promise<PatentResponse> {\n const params = buildParams({ _eq: { cpc_subgroup_id: cpcCode } }, [...DEFAULT_PATENT_FIELDS], { size: limit })\n const raw = await this.client.get<unknown>(\"patent/\", params)\n return looseParse(zPatentSuccessResponse, raw)\n }\n\n async lookupCpc(cpcCode: string): Promise<CpcSubclassResponse> {\n const params = buildParams({ _eq: { cpc_subclass_id: cpcCode } })\n const raw = await this.client.get<unknown>(\"cpc_subclass/\", params)\n return looseParse(zCpcSubclassSuccessResponse, raw)\n }\n\n async searchByIpc(ipcCode: string, limit = 25): Promise<PatentResponse> {\n const params = buildParams({ _eq: { ipc_class: ipcCode } }, [...DEFAULT_PATENT_FIELDS], { size: limit })\n const raw = await this.client.get<unknown>(\"patent/\", params)\n return looseParse(zPatentSuccessResponse, raw)\n }\n\n async lookupIpc(ipcCode: string): Promise<IpcResponse> {\n const params = buildParams({ _eq: { ipc_class: ipcCode } })\n const raw = await this.client.get<unknown>(\"ipc/\", params)\n return looseParse(zIpcClassificationSuccessResponse, raw)\n }\n\n private buildPatentQuery(query: string, searchType: \"text\" | \"assignee\" | \"inventor\"): Record<string, unknown> {\n switch (searchType) {\n case \"text\":\n return { _text_any: { patent_abstract: query } }\n case \"assignee\":\n return { _text_any: { assignee_organization: query } }\n case \"inventor\":\n return {\n _or: [{ _text_any: { inventor_name_first: query } }, { _text_any: { inventor_name_last: query } }],\n }\n }\n }\n}\n"],"mappings":"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"}