footnote-data 0.1.1 → 0.2.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 (3) hide show
  1. package/README.md +61 -4
  2. package/footnote.mjs +45 -2
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -2,10 +2,16 @@
2
2
 
3
3
  Employment-diligence data from primary public records: statutory WARN layoff
4
4
  notices, certified H-1B/LCA wage filings, USCIS petition outcomes, DOL Wage &
5
- Hour and OSHA enforcement, federal litigation posture, and severance terms
6
- parsed from SEC filings. Counts are measured, matches are exact-or-absent, and
7
- every response carries `data_gaps` absence of evidence is always
8
- distinguished from evidence of absence.
5
+ Hour and OSHA enforcement, DOL debarment, H-2 seasonal-labor and PERM green-card
6
+ certifications, ICE SEVP OPT/STEM-OPT top employers, federal litigation posture,
7
+ and severance terms parsed from SEC filings. Counts are measured, matches are
8
+ exact-or-absent, and absence of evidence is always distinguished from evidence
9
+ of absence.
10
+
11
+ Free keys get trust/posture answers (WARN, H-1B, debarment). The
12
+ volume/series datasets — H-2, PERM, OPT — are **Data Pro**; a free key hitting
13
+ them gets a `403 upgrade_required` that names the dataset and the way up, never
14
+ a silent 404. `footnote datasets` lists every holding with its `access` tier.
9
15
 
10
16
  Zero runtime dependencies. Node 18+. Docs and pricing: <https://usefootnote.com/data>.
11
17
 
@@ -124,6 +130,52 @@ footnote litigation "Example Corp"
124
130
  footnote severance "Example Corp"
125
131
  ```
126
132
 
133
+ ### Work authorization & debarment
134
+
135
+ ```bash
136
+ # DOL debarment status — free tier: current / lapsed / none + program labels
137
+ footnote debarment "Example Staffing LLC"
138
+
139
+ # H-2A/H-2B seasonal-labor certifications for an employer (Data Pro)
140
+ footnote h2 "Example Farms" --program h2a --fy 2026
141
+
142
+ # National H-2 KPIs + the USCIS approved-worker trend (Data Pro)
143
+ footnote h2 summary
144
+
145
+ # PERM green-card certification decision counts (Data Pro)
146
+ footnote perm "Example Corp" --fy 2026
147
+
148
+ # ICE SEVP Top-200 OPT / STEM-OPT employers, ranked (Data Pro)
149
+ footnote opt-top --fy 2024 --limit 25
150
+ ```
151
+
152
+ ```text
153
+ $ footnote debarment "Example Staffing LLC"
154
+ employer_query example staffing
155
+ matched true
156
+ status current
157
+ programs OFLC H-2A
158
+
159
+ tier: free
160
+ match: exact normalized legal name + registered spelling variants (never fuzzy); …
161
+ interpretation: status is derived at read time — 'current' = a debarment in force today …
162
+ ▲ upgrade: Full debarment history — dates, entity spelling, willful flag, and violation text — is on Data Pro
163
+ ```
164
+
165
+ Honesty rails these commands keep, straight from the record:
166
+
167
+ - **debarment** — a no-match is *not* a clean bill (it means no exact-legal-name
168
+ entry on the DOL list); `status` is derived at read time, never stored.
169
+ - **h2** — wages are RAW rates with their unit, **never annualized** (seasonal
170
+ work); worker counts are OFLC application workers, not visas issued.
171
+ - **h2 summary** — OFLC certification (intent) and USCIS approvals (outcome) are
172
+ different pipeline stages and are **never** divided into a conversion rate.
173
+ - **perm** — a PERM certification is DOL's *step one* of green-card sponsorship,
174
+ not a green card; there is **no prevailing-wage field**.
175
+ - **opt-top** — `opt_or_stem_opt_students` is the source's own combined count and
176
+ is **not** `opt_students + stem_opt_students` (a student in both programs is
177
+ counted once per program); these are students, not employees.
178
+
127
179
  ### Dataset provenance
128
180
 
129
181
  ```bash
@@ -234,5 +286,10 @@ that apply to that call.
234
286
  | `osha` | `GET /api/data/v1/osha/employer` |
235
287
  | `severance` | `GET /api/data/v1/severance/employer` |
236
288
  | `wage-comparison` | `GET /api/data/v1/wage-comparison/employer` |
289
+ | `debarment` | `GET /api/data/v1/debarment` |
290
+ | `h2` | `GET /api/data/v1/h2/employers` |
291
+ | `h2 summary` | `GET /api/data/v1/h2/summary` |
292
+ | `perm` | `GET /api/data/v1/perm/employers` |
293
+ | `opt-top` | `GET /api/data/v1/opt/top-employers` |
237
294
  | `datasets` | `GET /api/data/v1/datasets` |
238
295
  | `get <path>` | `GET <any /api/data/v1 path>` |
package/footnote.mjs CHANGED
@@ -6,7 +6,7 @@
6
6
  * params, read from the source, never guessed.
7
7
  */
8
8
 
9
- export const VERSION = "0.1.0";
9
+ export const VERSION = "0.2.0";
10
10
  export const DEFAULT_API_URL = "https://usefootnote.com";
11
11
 
12
12
  const UPGRADE_URL = "https://usefootnote.com/data";
@@ -38,6 +38,8 @@ const VALIDATORS = {
38
38
  nonNegInt: { ok: (v) => /^\d+$/.test(v), hint: "a non-negative integer" },
39
39
  date: { ok: (v) => /^\d{4}-\d{2}-\d{2}$/.test(v), hint: "a date formatted YYYY-MM-DD" },
40
40
  text3: { ok: (v) => v.trim().length >= 3, hint: "at least 3 characters" },
41
+ program: { ok: (v) => /^h2[ab]$/i.test(v), hint: "h2a or h2b", map: (v) => v.toLowerCase() },
42
+ year: { ok: (v) => /^\d{4}$/.test(v), hint: "a 4-digit year (e.g. 2024)" },
41
43
  };
42
44
 
43
45
  /**
@@ -122,6 +124,45 @@ export const COMMANDS = [
122
124
  summary: "Advertised (posting) vs DOL-attested (LCA) wages",
123
125
  positional: { param: "name", label: "<employer>", min: 2 },
124
126
  },
127
+ {
128
+ name: "debarment",
129
+ path: "/api/data/v1/debarment",
130
+ route: "app/api/data/v1/debarment/route.ts",
131
+ summary: "DOL debarment status: current / lapsed / none (free tier)",
132
+ positional: { param: "employer", label: "<employer>", min: 2 },
133
+ },
134
+ {
135
+ // Two-word "h2 summary" is matched before the one-word "h2" employer lookup
136
+ // (findCommand tries the 2-word join first), so both resolve unambiguously.
137
+ name: "h2 summary",
138
+ path: "/api/data/v1/h2/summary",
139
+ route: "app/api/data/v1/h2/summary/route.ts",
140
+ summary: "National H-2A/H-2B KPIs + USCIS worker trend (Data Pro)",
141
+ flags: {},
142
+ },
143
+ {
144
+ name: "h2",
145
+ path: "/api/data/v1/h2/employers",
146
+ route: "app/api/data/v1/h2/employers/route.ts",
147
+ summary: "H-2A/H-2B certifications for an employer (Data Pro)",
148
+ positional: { param: "name", label: "<employer>", min: 2 },
149
+ flags: { program: "program", fy: "year" },
150
+ },
151
+ {
152
+ name: "perm",
153
+ path: "/api/data/v1/perm/employers",
154
+ route: "app/api/data/v1/perm/employers/route.ts",
155
+ summary: "PERM green-card decision counts for an employer (Data Pro)",
156
+ positional: { param: "name", label: "<employer>", min: 2 },
157
+ flags: { fy: "year" },
158
+ },
159
+ {
160
+ name: "opt-top",
161
+ path: "/api/data/v1/opt/top-employers",
162
+ route: "app/api/data/v1/opt/top-employers/route.ts",
163
+ summary: "SEVP Top-200 OPT/STEM-OPT employers, ranked (Data Pro)",
164
+ flags: { fy: "year", limit: "posInt" },
165
+ },
125
166
  {
126
167
  name: "datasets",
127
168
  path: "/api/data/v1/datasets",
@@ -397,8 +438,10 @@ function renderApiError(status, body, headers, io, style) {
397
438
 
398
439
  export function helpText() {
399
440
  const rows = COMMANDS.map((c) => {
441
+ const flagLabel = (t) =>
442
+ t === "date" ? "YYYY-MM-DD" : t === "state" ? "CA" : t === "text3" ? "TEXT" : t === "program" ? "h2a|h2b" : t === "year" ? "YYYY" : "N";
400
443
  const flags = Object.entries(c.flags ?? {})
401
- .map(([f, t]) => `[--${f} ${t === "date" ? "YYYY-MM-DD" : t === "state" ? "CA" : t === "text3" ? "TEXT" : "N"}]`)
444
+ .map(([f, t]) => `[--${f} ${flagLabel(t)}]`)
402
445
  .join(" ");
403
446
  const pos = c.positional ? ` ${c.positional.label}` : "";
404
447
  return [` footnote ${c.name}${pos}${flags ? ` ${flags}` : ""}`, c.summary];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "footnote-data",
3
- "version": "0.1.1",
4
- "description": "The official Footnote CLI \u2014 career intelligence from the public record: WARN layoffs, H-1B & green-card sponsorship, certified wages, and federal enforcement, straight from usefootnote.com's Data API.",
3
+ "version": "0.2.0",
4
+ "description": "The official Footnote CLI \u2014 career intelligence from the public record: WARN layoffs, H-1B & green-card sponsorship, H-2 seasonal labor, PERM, OPT, DOL debarment, certified wages, and federal enforcement, straight from usefootnote.com's Data API.",
5
5
  "keywords": [
6
6
  "layoffs",
7
7
  "warn-act",