tn-elections-mcp 0.5.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 (77) hide show
  1. package/README.md +87 -0
  2. package/dist/api/easyvote-client.d.ts +51 -0
  3. package/dist/api/easyvote-client.js +254 -0
  4. package/dist/api/easyvote-client.js.map +1 -0
  5. package/dist/api/easyvote-client.test.d.ts +1 -0
  6. package/dist/api/easyvote-client.test.js +47 -0
  7. package/dist/api/easyvote-client.test.js.map +1 -0
  8. package/dist/api/gemini-pdf.d.ts +23 -0
  9. package/dist/api/gemini-pdf.js +261 -0
  10. package/dist/api/gemini-pdf.js.map +1 -0
  11. package/dist/api/sos-client.d.ts +15 -0
  12. package/dist/api/sos-client.js +74 -0
  13. package/dist/api/sos-client.js.map +1 -0
  14. package/dist/api/sumner-client.d.ts +12 -0
  15. package/dist/api/sumner-client.js +57 -0
  16. package/dist/api/sumner-client.js.map +1 -0
  17. package/dist/api/tncamp-client.d.ts +61 -0
  18. package/dist/api/tncamp-client.js +310 -0
  19. package/dist/api/tncamp-client.js.map +1 -0
  20. package/dist/data/sumner-cycles.d.ts +3 -0
  21. package/dist/data/sumner-cycles.js +19 -0
  22. package/dist/data/sumner-cycles.js.map +1 -0
  23. package/dist/data/sumner-cycles.test.d.ts +1 -0
  24. package/dist/data/sumner-cycles.test.js +29 -0
  25. package/dist/data/sumner-cycles.test.js.map +1 -0
  26. package/dist/data/tn-counties.d.ts +23 -0
  27. package/dist/data/tn-counties.js +162 -0
  28. package/dist/data/tn-counties.js.map +1 -0
  29. package/dist/data/tn-counties.test.d.ts +1 -0
  30. package/dist/data/tn-counties.test.js +71 -0
  31. package/dist/data/tn-counties.test.js.map +1 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +31 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/parsers/sos-xlsx.d.ts +24 -0
  36. package/dist/parsers/sos-xlsx.js +149 -0
  37. package/dist/parsers/sos-xlsx.js.map +1 -0
  38. package/dist/parsers/sos-xlsx.test.d.ts +1 -0
  39. package/dist/parsers/sos-xlsx.test.js +111 -0
  40. package/dist/parsers/sos-xlsx.test.js.map +1 -0
  41. package/dist/parsers/sumner-html.d.ts +8 -0
  42. package/dist/parsers/sumner-html.js +200 -0
  43. package/dist/parsers/sumner-html.js.map +1 -0
  44. package/dist/parsers/sumner-html.test.d.ts +1 -0
  45. package/dist/parsers/sumner-html.test.js +79 -0
  46. package/dist/parsers/sumner-html.test.js.map +1 -0
  47. package/dist/parsers/tncamp-form.d.ts +15 -0
  48. package/dist/parsers/tncamp-form.js +54 -0
  49. package/dist/parsers/tncamp-form.js.map +1 -0
  50. package/dist/parsers/tncamp-form.test.d.ts +1 -0
  51. package/dist/parsers/tncamp-form.test.js +114 -0
  52. package/dist/parsers/tncamp-form.test.js.map +1 -0
  53. package/dist/parsers/tncamp-report.d.ts +6 -0
  54. package/dist/parsers/tncamp-report.js +189 -0
  55. package/dist/parsers/tncamp-report.js.map +1 -0
  56. package/dist/parsers/tncamp-results.d.ts +10 -0
  57. package/dist/parsers/tncamp-results.js +113 -0
  58. package/dist/parsers/tncamp-results.js.map +1 -0
  59. package/dist/parsers/tncamp-results.test.d.ts +1 -0
  60. package/dist/parsers/tncamp-results.test.js +86 -0
  61. package/dist/parsers/tncamp-results.test.js.map +1 -0
  62. package/dist/tools/easyvote.d.ts +2 -0
  63. package/dist/tools/easyvote.js +382 -0
  64. package/dist/tools/easyvote.js.map +1 -0
  65. package/dist/tools/sos.d.ts +2 -0
  66. package/dist/tools/sos.js +130 -0
  67. package/dist/tools/sos.js.map +1 -0
  68. package/dist/tools/sumner.d.ts +2 -0
  69. package/dist/tools/sumner.js +134 -0
  70. package/dist/tools/sumner.js.map +1 -0
  71. package/dist/tools/tncamp.d.ts +2 -0
  72. package/dist/tools/tncamp.js +401 -0
  73. package/dist/tools/tncamp.js.map +1 -0
  74. package/dist/types.d.ts +270 -0
  75. package/dist/types.js +5 -0
  76. package/dist/types.js.map +1 -0
  77. package/package.json +47 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * tncamp (Tennessee Registry of Election Finance) HTTP client.
3
+ *
4
+ * Session-based Java web app at apps.tn.gov/tncamp/public/.
5
+ * Flow: GET form → POST → 302 redirect → GET results page.
6
+ * Responses are Windows-1252 encoded.
7
+ */
8
+ import { parseResultsTable, parsePaginationInfo } from '../parsers/tncamp-results.js';
9
+ import { parseReportDetail } from '../parsers/tncamp-report.js';
10
+ import { parseFormOptions, parseDistrictsJson } from '../parsers/tncamp-form.js';
11
+ const BASE = 'https://apps.tn.gov/tncamp/public';
12
+ const SEARCH_BASE = 'https://apps.tn.gov/tncamp/search/pub';
13
+ const TIMEOUT_MS = 10_000;
14
+ const MAX_PAGES = 20;
15
+ const PAGE_DELAY_MS = 300;
16
+ async function fetchWithTimeout(url, options = {}) {
17
+ const controller = new AbortController();
18
+ const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
19
+ try {
20
+ return await fetch(url, { ...options, signal: controller.signal });
21
+ }
22
+ finally {
23
+ clearTimeout(timeout);
24
+ }
25
+ }
26
+ async function decodeBody(response) {
27
+ const buffer = await response.arrayBuffer();
28
+ return new TextDecoder('windows-1252').decode(buffer);
29
+ }
30
+ function extractSessionCookie(response) {
31
+ const setCookie = response.headers.get('set-cookie') || '';
32
+ const match = setCookie.match(/JSESSIONID="?([^";]+)/);
33
+ return match ? `JSESSIONID=${match[1]}` : null;
34
+ }
35
+ async function startSession(formPath = 'cpsearch.htm') {
36
+ const response = await fetchWithTimeout(`${BASE}/${formPath}`);
37
+ await response.arrayBuffer();
38
+ const cookie = extractSessionCookie(response);
39
+ if (!cookie) {
40
+ throw new Error(`Failed to get session cookie from ${formPath}`);
41
+ }
42
+ return { cookie };
43
+ }
44
+ async function submitForm(session, formPath, params) {
45
+ const postResponse = await fetchWithTimeout(`${BASE}/${formPath}`, {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/x-www-form-urlencoded',
49
+ 'Cookie': session.cookie,
50
+ 'Referer': `${BASE}/${formPath}`,
51
+ },
52
+ body: params.toString(),
53
+ redirect: 'manual',
54
+ });
55
+ // If POST returns 200 instead of 302, a required param may be missing.
56
+ // Detect the search form specifically (not just any <form> — results pages also have nav forms).
57
+ if (postResponse.status === 200) {
58
+ const body = await decodeBody(postResponse);
59
+ if (body.includes('id="frmCandidates"') || body.includes('id="frmContributions"') || body.includes('id="frmReports"')) {
60
+ throw new Error('Search form returned without results — a required parameter may be missing (e.g., yearSelection for contribution/expenditure searches)');
61
+ }
62
+ return body;
63
+ }
64
+ const location = postResponse.headers.get('location');
65
+ if (!location) {
66
+ return decodeBody(postResponse);
67
+ }
68
+ const resultsUrl = location.startsWith('http') ? location : `https://apps.tn.gov${location}`;
69
+ const resultsResponse = await fetchWithTimeout(resultsUrl, {
70
+ headers: { 'Cookie': session.cookie },
71
+ });
72
+ return decodeBody(resultsResponse);
73
+ }
74
+ async function fetchPage(session, resultsPath, page, paginationParam) {
75
+ const url = `${BASE}/${resultsPath}?${paginationParam}=${page}`;
76
+ const response = await fetchWithTimeout(url, {
77
+ headers: { 'Cookie': session.cookie },
78
+ });
79
+ return decodeBody(response);
80
+ }
81
+ function delay(ms) {
82
+ return new Promise(resolve => setTimeout(resolve, ms));
83
+ }
84
+ // ============================================================
85
+ // All 16 report selection values (must send all for complete results)
86
+ // ============================================================
87
+ const ALL_REPORT_SELECTIONS = Array.from({ length: 16 }, (_, i) => String(i + 1));
88
+ // ============================================================
89
+ // Form options & district lookup (office-by-district search)
90
+ // ============================================================
91
+ const FORM_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
92
+ let formOptionsCache = null;
93
+ const districtCache = new Map();
94
+ export async function getFormOptions() {
95
+ if (formOptionsCache && Date.now() - formOptionsCache.fetchedAt < FORM_CACHE_TTL_MS) {
96
+ return formOptionsCache.data;
97
+ }
98
+ const response = await fetchWithTimeout(`${BASE}/cpsearch.htm`);
99
+ const html = await decodeBody(response);
100
+ const options = parseFormOptions(html);
101
+ formOptionsCache = { data: options, fetchedAt: Date.now() };
102
+ return options;
103
+ }
104
+ export async function getDistricts(officeId) {
105
+ const cached = districtCache.get(officeId);
106
+ if (cached && Date.now() - cached.fetchedAt < FORM_CACHE_TTL_MS) {
107
+ return cached.data;
108
+ }
109
+ // Districts endpoint returns JSON, no session cookie needed
110
+ const response = await fetchWithTimeout(`${BASE}/districts.htm?officeId=${officeId}`, {
111
+ method: 'POST',
112
+ });
113
+ const json = await response.text();
114
+ const districts = parseDistrictsJson(json, officeId);
115
+ districtCache.set(officeId, { data: districts, fetchedAt: Date.now() });
116
+ return districts;
117
+ }
118
+ export async function resolveOffice(nameOrId) {
119
+ const options = await getFormOptions();
120
+ const q = nameOrId.toLowerCase();
121
+ // Try exact ID match first
122
+ const byId = options.offices.find(o => o.id === nameOrId);
123
+ if (byId)
124
+ return byId;
125
+ // Case-insensitive includes match
126
+ return options.offices.find(o => o.name.toLowerCase().includes(q)) || null;
127
+ }
128
+ export async function resolveDistrict(officeId, labelOrId) {
129
+ const districts = await getDistricts(officeId);
130
+ // Try exact ID match
131
+ const byId = districts.find(d => d.id === labelOrId);
132
+ if (byId)
133
+ return byId;
134
+ // Case-insensitive label match
135
+ const q = labelOrId.toLowerCase();
136
+ return districts.find(d => d.label.toLowerCase() === q) || null;
137
+ }
138
+ export async function resolveElectionYear(yearStr) {
139
+ const options = await getFormOptions();
140
+ // Try exact ID match
141
+ const byId = options.electionYears.find(y => y.id === yearStr);
142
+ if (byId)
143
+ return byId;
144
+ // Match by year label (e.g., "2026" matches "2026")
145
+ return options.electionYears.find(y => y.label.startsWith(yearStr)) || null;
146
+ }
147
+ export async function resolveParty(nameOrId) {
148
+ const options = await getFormOptions();
149
+ const byId = options.parties.find(p => p.id === nameOrId);
150
+ if (byId)
151
+ return byId;
152
+ const q = nameOrId.toLowerCase();
153
+ return options.parties.find(p => p.name.toLowerCase().includes(q)) || null;
154
+ }
155
+ export async function searchCandidates(params) {
156
+ const session = await startSession();
157
+ // Office-based search (no name) requires searchType=candidate.
158
+ // Name-based search uses searchType=both (searchType=candidate without
159
+ // office params returns 200 form re-display).
160
+ const isOfficeSearch = !params.name && params.officeId;
161
+ const searchType = isOfficeSearch ? 'candidate' : 'both';
162
+ const form = new URLSearchParams();
163
+ form.set('searchType', searchType);
164
+ form.set('name', params.name || '');
165
+ form.set('officeSelection', params.officeId || '');
166
+ form.set('districtSelection', params.district || '');
167
+ form.set('electionYearSelection', params.electionYearId || '');
168
+ form.set('partySelection', params.partyId || '');
169
+ form.set('nameField', 'true');
170
+ form.set('partyField', 'true');
171
+ form.set('officeField', 'true');
172
+ form.set('districtField', 'true');
173
+ form.set('electionYearField', 'true');
174
+ form.set('_continue', 'Search');
175
+ const html = await submitForm(session, 'cpsearch.htm', form);
176
+ let candidates = parseResultsTable(html, 'candidate');
177
+ const pagination = parsePaginationInfo(html);
178
+ if (pagination && pagination.totalPages > 1) {
179
+ for (let page = 2; page <= Math.min(pagination.totalPages, MAX_PAGES); page++) {
180
+ await delay(PAGE_DELAY_MS);
181
+ const pageHtml = await fetchPage(session, 'cpresults.htm', page, pagination.paginationParam);
182
+ candidates.push(...parseResultsTable(pageHtml, 'candidate'));
183
+ }
184
+ }
185
+ // Client-side filter by searchType (server always returns both)
186
+ if (params.searchType === 'candidate') {
187
+ candidates = candidates.filter(c => c.officeSought.toLowerCase() !== 'pac');
188
+ }
189
+ else if (params.searchType === 'pac') {
190
+ candidates = candidates.filter(c => c.officeSought.toLowerCase() === 'pac');
191
+ }
192
+ return candidates;
193
+ }
194
+ export async function getCandidateReports(candidateId, ownerName) {
195
+ // replist.htm needs a session cookie but no POST
196
+ const session = await startSession();
197
+ const url = `${BASE}/replist.htm?id=${candidateId}&owner=${encodeURIComponent(ownerName)}`;
198
+ const response = await fetchWithTimeout(url, {
199
+ headers: { 'Cookie': session.cookie },
200
+ });
201
+ const html = await decodeBody(response);
202
+ return parseResultsTable(html, 'report');
203
+ }
204
+ export async function getReportDetail(reportId) {
205
+ // report_full.htm needs a session cookie but no POST
206
+ const session = await startSession();
207
+ const url = `${SEARCH_BASE}/report_full.htm?reportId=${reportId}`;
208
+ const response = await fetchWithTimeout(url, {
209
+ headers: { 'Cookie': session.cookie },
210
+ });
211
+ const html = await decodeBody(response);
212
+ return parseReportDetail(html, reportId);
213
+ }
214
+ function buildCeFormData(searchType, params) {
215
+ const form = new URLSearchParams();
216
+ form.set('searchType', searchType);
217
+ form.set('toType', 'both');
218
+ form.set('candName', params.candName || '');
219
+ form.set('yearSelection', params.year);
220
+ form.set('electionYearSelection', params.electionYearId || '');
221
+ form.set('typeOf', params.typeOf || 'all');
222
+ if (params.amountDollars !== undefined) {
223
+ form.set('amountDollars', String(params.amountDollars));
224
+ form.set('amountCents', '0');
225
+ form.set('amountSelection', params.amountSelection || 'greater');
226
+ }
227
+ else {
228
+ form.set('amountDollars', '');
229
+ form.set('amountCents', '');
230
+ form.set('amountSelection', 'equal');
231
+ }
232
+ for (const r of ALL_REPORT_SELECTIONS) {
233
+ form.append('reportSelection', r);
234
+ }
235
+ form.set('fromCandidate', 'true');
236
+ form.set('fromPAC', 'true');
237
+ form.set('fromIndividual', 'true');
238
+ form.set('fromOrganization', 'true');
239
+ form.set('toCandidate', 'true');
240
+ form.set('toPac', 'true');
241
+ form.set('toOther', 'true');
242
+ if (searchType === 'contributions') {
243
+ const cp = params;
244
+ form.set('contributorName', cp.contributorName || '');
245
+ form.set('recipientName', '');
246
+ form.set('employer', cp.employer || '');
247
+ form.set('occupation', cp.occupation || '');
248
+ form.set('zipCode', cp.zipCode || '');
249
+ form.set('vendorName', '');
250
+ form.set('vendorZipCode', '');
251
+ form.set('purpose', '');
252
+ form.set('typeField', 'true');
253
+ form.set('amountField', 'true');
254
+ form.set('dateField', 'true');
255
+ form.set('electionYearField', 'true');
256
+ form.set('recipientNameField', 'true');
257
+ form.set('contributorNameField', 'true');
258
+ form.set('contributorAddressField', 'true');
259
+ form.set('contributorOccupationField', 'true');
260
+ form.set('contributorEmployerField', 'true');
261
+ }
262
+ else {
263
+ const ep = params;
264
+ form.set('contributorName', '');
265
+ form.set('recipientName', '');
266
+ form.set('employer', '');
267
+ form.set('occupation', '');
268
+ form.set('zipCode', '');
269
+ form.set('vendorName', ep.vendorName || '');
270
+ form.set('vendorZipCode', ep.vendorZipCode || '');
271
+ form.set('purpose', ep.purpose || '');
272
+ form.set('typeField', 'true');
273
+ form.set('amountField', 'true');
274
+ form.set('dateField', 'true');
275
+ form.set('vendorNameField', 'true');
276
+ form.set('vendorAddressField', 'true');
277
+ form.set('purposeField', 'true');
278
+ form.set('candidateForField', 'true');
279
+ }
280
+ form.set('_continue', 'Search');
281
+ return form;
282
+ }
283
+ async function fetchAllPages(session, firstPageHtml, resultsPath, tableType) {
284
+ const items = parseResultsTable(firstPageHtml, tableType);
285
+ const pagination = parsePaginationInfo(firstPageHtml);
286
+ const totalCount = pagination?.totalItems || items.length;
287
+ if (pagination && pagination.totalPages > 1) {
288
+ const pagesToFetch = Math.min(pagination.totalPages, MAX_PAGES);
289
+ for (let page = 2; page <= pagesToFetch; page++) {
290
+ await delay(PAGE_DELAY_MS);
291
+ const pageHtml = await fetchPage(session, resultsPath, page, pagination.paginationParam);
292
+ items.push(...parseResultsTable(pageHtml, tableType));
293
+ }
294
+ }
295
+ const truncated = pagination ? pagination.totalPages > MAX_PAGES : false;
296
+ return { items, totalCount, truncated };
297
+ }
298
+ export async function searchContributions(params) {
299
+ const session = await startSession('cesearch.htm');
300
+ const form = buildCeFormData('contributions', params);
301
+ const html = await submitForm(session, 'cesearch.htm', form);
302
+ return fetchAllPages(session, html, 'ceresults.htm', 'contribution');
303
+ }
304
+ export async function searchExpenditures(params) {
305
+ const session = await startSession('cesearch.htm');
306
+ const form = buildCeFormData('expenditures', params);
307
+ const html = await submitForm(session, 'cesearch.htm', form);
308
+ return fetchAllPages(session, html, 'ceresults.htm', 'expenditure');
309
+ }
310
+ //# sourceMappingURL=tncamp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tncamp-client.js","sourceRoot":"","sources":["../../src/api/tncamp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SumnerElectionCycle } from '../types.js';
2
+ export declare const SUMNER_CYCLES: SumnerElectionCycle[];
3
+ export declare function resolveCycle(input: string): SumnerElectionCycle | null;
@@ -0,0 +1,19 @@
1
+ export const SUMNER_CYCLES = [
2
+ { year: '2028', url: 'https://www.votesumnertn.org/financial-disclosures-2028-election-cycle/', label: '2028 Election Cycle' },
3
+ { year: '2026', url: 'https://www.votesumnertn.org/financial-disclosures-2026-election-cycle/', label: '2026 Election Cycle' },
4
+ { year: '2024', url: 'https://www.votesumnertn.org/financial-disclosures-2024-election-cycle/', label: '2024 Election Cycle' },
5
+ { year: '2023', url: 'https://www.votesumnertn.org/financial-disclosures-2023-election-cycle/', label: '2023 Election Cycle' },
6
+ { year: '2022', url: 'https://www.votesumnertn.org/financial-disclosures-2022-election-cycle/', label: '2022 Election Cycle' },
7
+ { year: '2020', url: 'https://www.votesumnertn.org/financial-disclosures-2020-election-cycle/', label: '2020 Election Cycle' },
8
+ { year: '2016-2018', url: 'https://www.votesumnertn.org/financial-disclosures-2016-and-2018-election-cycles/', label: '2016 & 2018 Election Cycles' },
9
+ ];
10
+ export function resolveCycle(input) {
11
+ const lower = input.toLowerCase().trim();
12
+ if (!lower)
13
+ return null;
14
+ const exact = SUMNER_CYCLES.find(c => c.year === lower);
15
+ if (exact)
16
+ return exact;
17
+ return SUMNER_CYCLES.find(c => c.year.includes(lower)) || null;
18
+ }
19
+ //# sourceMappingURL=sumner-cycles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sumner-cycles.js","sourceRoot":"","sources":["../../src/data/sumner-cycles.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAA0B;IAClD,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,yEAAyE,EAAE,KAAK,EAAE,qBAAqB,EAAE;IAC9H,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,mFAAmF,EAAE,KAAK,EAAE,6BAA6B,EAAE;CACtJ,CAAA;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAA;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IACvD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAA;IACvB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAA;AAChE,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { SUMNER_CYCLES, resolveCycle } from './sumner-cycles.js';
3
+ describe('SUMNER_CYCLES', () => {
4
+ it('has 7 entries', () => {
5
+ expect(SUMNER_CYCLES).toHaveLength(7);
6
+ });
7
+ it('all have required fields', () => {
8
+ for (const c of SUMNER_CYCLES) {
9
+ expect(c.year).toBeTruthy();
10
+ expect(c.url).toContain('votesumnertn.org');
11
+ expect(c.label).toBeTruthy();
12
+ }
13
+ });
14
+ });
15
+ describe('resolveCycle', () => {
16
+ it('resolves exact year', () => {
17
+ expect(resolveCycle('2026')?.year).toBe('2026');
18
+ });
19
+ it('resolves partial year for combined cycle', () => {
20
+ expect(resolveCycle('2016')?.year).toBe('2016-2018');
21
+ });
22
+ it('returns null for unknown year', () => {
23
+ expect(resolveCycle('1999')).toBeNull();
24
+ });
25
+ it('returns null for empty string', () => {
26
+ expect(resolveCycle('')).toBeNull();
27
+ });
28
+ });
29
+ //# sourceMappingURL=sumner-cycles.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sumner-cycles.test.js","sourceRoot":"","sources":["../../src/data/sumner-cycles.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEhE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;QACvB,MAAM,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAA;YAC3B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;YAC3C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Tennessee county data: 95 county codes, 14 EasyVote campaign finance configs,
3
+ * and resolution helpers.
4
+ *
5
+ * EasyVote tenant IDs verified via live API scan (2026-03-25).
6
+ * See ~/Projects/_scratch/tn-easyvote-county-scan.md for details.
7
+ */
8
+ export interface EasyVoteCountyConfig {
9
+ slug: string;
10
+ name: string;
11
+ tenantId: string;
12
+ filerCount: number;
13
+ countySeat: string;
14
+ }
15
+ export declare const EASYVOTE_COUNTIES: EasyVoteCountyConfig[];
16
+ /**
17
+ * Resolve a county input to an EasyVote config.
18
+ * Accepts: county name ("Knox"), slug ("knoxcountytn"), county seat ("Knoxville"),
19
+ * or partial match ("david" → Davidson).
20
+ */
21
+ export declare function resolveCounty(input: string): EasyVoteCountyConfig | null;
22
+ export declare const TN_COUNTIES: Record<string, string>;
23
+ export declare const TN_COUNTY_NAMES: Map<string, string>;
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Tennessee county data: 95 county codes, 14 EasyVote campaign finance configs,
3
+ * and resolution helpers.
4
+ *
5
+ * EasyVote tenant IDs verified via live API scan (2026-03-25).
6
+ * See ~/Projects/_scratch/tn-easyvote-county-scan.md for details.
7
+ */
8
+ // 14 counties with active EasyVote Campaign Finance portals
9
+ export const EASYVOTE_COUNTIES = [
10
+ { slug: 'andersoncountytn', name: 'Anderson', tenantId: 'F3FFF032-32E1-46E6-9FE7-D27E29ED5190', filerCount: 0, countySeat: 'Clinton' },
11
+ { slug: 'davidsoncountytn', name: 'Davidson', tenantId: '1A0C899A-456B-4913-BFF0-4A8B0AE932A1', filerCount: 349, countySeat: 'Nashville' },
12
+ { slug: 'greenecountytn', name: 'Greene', tenantId: 'B703BCE6-0E9C-4C19-B17C-0D6969D1E507', filerCount: 18, countySeat: 'Greeneville' },
13
+ { slug: 'hamblencountytn', name: 'Hamblen', tenantId: 'B4520609-C0BC-43FE-ADC4-04C6C1E02872', filerCount: 54, countySeat: 'Morristown' },
14
+ { slug: 'hamiltoncountytn', name: 'Hamilton', tenantId: '0F5A08EE-617A-4B11-AD30-E963AE98E120', filerCount: 344, countySeat: 'Chattanooga' },
15
+ { slug: 'knoxcountytn', name: 'Knox', tenantId: '4BB07902-FDCA-4D3B-BF6F-EA8F3A3E99A4', filerCount: 147, countySeat: 'Knoxville' },
16
+ { slug: 'madisoncountytn', name: 'Madison', tenantId: 'B97BABE0-EB4E-498E-9C15-A2274E75B1FF', filerCount: 0, countySeat: 'Jackson' },
17
+ { slug: 'marioncountytn', name: 'Marion', tenantId: '64B80BAC-CC7E-4287-986F-E7200BA3C357', filerCount: 0, countySeat: 'Jasper' },
18
+ { slug: 'maurycountytn', name: 'Maury', tenantId: 'B5C91383-E324-410A-812E-826D6F5AF93F', filerCount: 89, countySeat: 'Columbia' },
19
+ { slug: 'rutherfordcountytn', name: 'Rutherford', tenantId: '09ECD306-F24C-4CDD-9580-F9815F736BD5', filerCount: 205, countySeat: 'Murfreesboro' },
20
+ { slug: 'shelbycountytn', name: 'Shelby', tenantId: 'EE6EBC62-7B7C-432F-869E-4DE111271E07', filerCount: 496, countySeat: 'Memphis' },
21
+ { slug: 'sullivancountytn', name: 'Sullivan', tenantId: '6074E035-D00A-404F-8A84-6ED696F1378D', filerCount: 347, countySeat: 'Blountville' },
22
+ { slug: 'washingtoncountytn', name: 'Washington', tenantId: '683CABF8-1501-48E7-A4DE-A68A9DF9E44F', filerCount: 114, countySeat: 'Jonesborough' },
23
+ { slug: 'williamsoncountytn', name: 'Williamson', tenantId: '38C18856-1015-498C-9A35-D162A05FA0DF', filerCount: 215, countySeat: 'Franklin' },
24
+ ];
25
+ // Reverse lookups for resolveCounty()
26
+ const BY_NAME = new Map(EASYVOTE_COUNTIES.map(c => [c.name.toLowerCase(), c]));
27
+ const BY_SLUG = new Map(EASYVOTE_COUNTIES.map(c => [c.slug, c]));
28
+ const BY_SEAT = new Map(EASYVOTE_COUNTIES.map(c => [c.countySeat.toLowerCase(), c]));
29
+ /**
30
+ * Resolve a county input to an EasyVote config.
31
+ * Accepts: county name ("Knox"), slug ("knoxcountytn"), county seat ("Knoxville"),
32
+ * or partial match ("david" → Davidson).
33
+ */
34
+ export function resolveCounty(input) {
35
+ const lower = input.toLowerCase().trim();
36
+ if (!lower)
37
+ return null;
38
+ // Exact match by name
39
+ const byName = BY_NAME.get(lower);
40
+ if (byName)
41
+ return byName;
42
+ // Exact match by slug
43
+ const bySlug = BY_SLUG.get(lower);
44
+ if (bySlug)
45
+ return bySlug;
46
+ // Exact match by county seat
47
+ const bySeat = BY_SEAT.get(lower);
48
+ if (bySeat)
49
+ return bySeat;
50
+ // Partial match on name (prefix)
51
+ for (const county of EASYVOTE_COUNTIES) {
52
+ if (county.name.toLowerCase().startsWith(lower))
53
+ return county;
54
+ }
55
+ // Partial match on county seat
56
+ for (const county of EASYVOTE_COUNTIES) {
57
+ if (county.countySeat.toLowerCase().startsWith(lower))
58
+ return county;
59
+ }
60
+ return null;
61
+ }
62
+ // All 95 Tennessee counties with FIPS codes (for Phase 3 disclosures)
63
+ export const TN_COUNTIES = {
64
+ '001': 'Anderson',
65
+ '003': 'Bedford',
66
+ '005': 'Benton',
67
+ '007': 'Bledsoe',
68
+ '009': 'Blount',
69
+ '011': 'Bradley',
70
+ '013': 'Campbell',
71
+ '015': 'Cannon',
72
+ '017': 'Carroll',
73
+ '019': 'Carter',
74
+ '021': 'Cheatham',
75
+ '023': 'Chester',
76
+ '025': 'Claiborne',
77
+ '027': 'Clay',
78
+ '029': 'Cocke',
79
+ '031': 'Coffee',
80
+ '033': 'Crockett',
81
+ '035': 'Cumberland',
82
+ '037': 'Davidson',
83
+ '039': 'Decatur',
84
+ '041': 'DeKalb',
85
+ '043': 'Dickson',
86
+ '045': 'Dyer',
87
+ '047': 'Fayette',
88
+ '049': 'Fentress',
89
+ '051': 'Franklin',
90
+ '053': 'Gibson',
91
+ '055': 'Giles',
92
+ '057': 'Grainger',
93
+ '059': 'Greene',
94
+ '061': 'Grundy',
95
+ '063': 'Hamblen',
96
+ '065': 'Hamilton',
97
+ '067': 'Hancock',
98
+ '069': 'Hardeman',
99
+ '071': 'Hardin',
100
+ '073': 'Hawkins',
101
+ '075': 'Haywood',
102
+ '077': 'Henderson',
103
+ '079': 'Henry',
104
+ '081': 'Hickman',
105
+ '083': 'Houston',
106
+ '085': 'Humphreys',
107
+ '087': 'Jackson',
108
+ '089': 'Jefferson',
109
+ '091': 'Johnson',
110
+ '093': 'Knox',
111
+ '095': 'Lake',
112
+ '097': 'Lauderdale',
113
+ '099': 'Lawrence',
114
+ '101': 'Lewis',
115
+ '103': 'Lincoln',
116
+ '105': 'Loudon',
117
+ '107': 'Macon',
118
+ '109': 'Madison',
119
+ '111': 'Marion',
120
+ '113': 'Marshall',
121
+ '115': 'Maury',
122
+ '117': 'McMinn',
123
+ '119': 'McNairy',
124
+ '121': 'Meigs',
125
+ '123': 'Monroe',
126
+ '125': 'Montgomery',
127
+ '127': 'Moore',
128
+ '129': 'Morgan',
129
+ '131': 'Obion',
130
+ '133': 'Overton',
131
+ '135': 'Perry',
132
+ '137': 'Pickett',
133
+ '139': 'Polk',
134
+ '141': 'Putnam',
135
+ '143': 'Rhea',
136
+ '145': 'Roane',
137
+ '147': 'Robertson',
138
+ '149': 'Rutherford',
139
+ '151': 'Scott',
140
+ '153': 'Sequatchie',
141
+ '155': 'Sevier',
142
+ '157': 'Shelby',
143
+ '159': 'Smith',
144
+ '161': 'Stewart',
145
+ '163': 'Sullivan',
146
+ '165': 'Sumner',
147
+ '167': 'Tipton',
148
+ '169': 'Trousdale',
149
+ '171': 'Unicoi',
150
+ '173': 'Union',
151
+ '175': 'Van Buren',
152
+ '177': 'Warren',
153
+ '179': 'Washington',
154
+ '181': 'Wayne',
155
+ '183': 'Weakley',
156
+ '185': 'White',
157
+ '187': 'Williamson',
158
+ '189': 'Wilson',
159
+ };
160
+ // Reverse lookup: lowercase name → FIPS code
161
+ export const TN_COUNTY_NAMES = new Map(Object.entries(TN_COUNTIES).map(([code, name]) => [name.toLowerCase(), code]));
162
+ //# sourceMappingURL=tn-counties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tn-counties.js","sourceRoot":"","sources":["../../src/data/tn-counties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};