Convert project to ES modules (align tooling with the service repo)#276
Convert project to ES modules (align tooling with the service repo)#276bickelj-agent wants to merge 2 commits into
service repo)#276Conversation
With `"type": "module"`, Node resolves `.js` files as ESM, so the already-present `nodenext` setting now requires explicit `.js` suffixes on relative imports, and running the scripts from `src/` needs a loader mapping those suffixes back to their `.ts` source. This change is only what ESM forces (the suffixes, the `ts-node` ESM register hook the dev scripts now import, and the type field) so it can stand alone and stay reviewable; the service repo's broader tooling is deferred to the next commit. The legacy ESLint config and single tsconfig are kept, since they already use `nodenext` and still lint the ESM source. Generated-by: GLM-5.2
service repo)
service repo)
|
I was able to run the charity navigator @slifty @hminsky2002 I don't think it would be best for the one who prompted this PR to also be the one to review this PR, so I would appreciate one of y'all's reviews. |
There was a problem hiding this comment.
Pull request overview
This pull request migrates data-scripts from CommonJS to ES modules and then aligns the repo’s TypeScript, linting/formatting, and test tooling with the stricter standards used in the service repository, while minimizing diff churn in pre-existing scripts.
Changes:
- Switch Node execution and internal imports to ESM (
"type": "module",.jsimport specifiers, ts-node ESM loader hook). - Split TypeScript configs into build vs dev/typecheck, and add Jest-based unit tests for key parsing helpers.
- Replace legacy ESLint config with ESLint 9 flat config + Prettier, plus editor/npm configuration alignment.
Reviewed changes
Copilot reviewed 22 out of 25 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Introduces build output settings (dist/) and declaration emit for ESM build. |
| tsconfig.dev.json | Adds a dev/typecheck-only TS config used by linting and tests. |
| src/postProposalVersions.ts | Updates Node core imports and ESM-relative import specifiers; replaces inline literals with named constants. |
| src/pdc-api.ts | Updates ESM import specifiers and makes type re-exports explicit. |
| src/oidc.ts | Switches Node core import to node: prefix and adopts type imports for ESM hygiene. |
| src/index.ts | Updates internal imports to .js specifiers required under Node ESM. |
| src/generateBaseFieldsInserts.ts | Converts Node core imports to node: prefix and updates internal imports to .js. |
| src/generateApplicationFormJson.ts | Updates internal imports to .js and corrects axios type-only import usage. |
| src/ein.unit.test.ts | Adds Jest unit tests for EIN validation behavior. |
| src/csv.unit.test.ts | Adds Jest unit tests for CSV row assertion behavior. |
| src/csv.ts | Switches assert import to node: prefix. |
| src/client.ts | Updates internal logger import to .js and uses type-only axios imports. |
| src/charityNavigator.ts | Updates Node/core and internal ESM imports; extracts JSON formatting constants. |
| src/candid.ts | Updates Node/core and internal ESM imports; extracts JSON/rate-limit constants. |
| register-ts-node-esm.mjs | Adds a Node --import hook to register ts-node/esm for running TS entrypoints under ESM. |
| package.json | Sets "type": "module", adds build/lint/format/test scripts, pins Node engine to 24, and updates dev tooling deps. |
| jest.config.cjs | Adds Jest configuration for ESM + ts-jest + .js specifier mapping. |
| eslint.config.mjs | Replaces legacy ESLint config with ESLint 9 flat config aligned to service tooling. |
| .prettierrc | Adds repo Prettier settings (single quotes, 120 print width). |
| .prettierignore | Avoids formatting churn on pre-existing scripts and legacy docs/configs. |
| .npmrc | Enables engine-strict to enforce the Node 24 engine constraint. |
| .gitignore | Adds local conversion-notes doc to ignore list. |
| .eslintrc.json | Removes legacy ESLint config in favor of flat config. |
| .editorconfig | Adds baseline editor formatting rules aligned with new tooling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
There is a raft of dependency updates pending, and I suspected those could be more easily merged/adapted if we changed this project to ESM, maybe that was incorrect, but that was also part of the impetus. |
bickelj
left a comment
There was a problem hiding this comment.
You're missing some newlines, GLM.
The data-scripts predate the shared, stricter tooling the service repository standardizes on, so this brings them in line so both repos lint, format, type-check, and test the same way: the flat ESLint 9 config on `eslint-config-love`, Prettier, the split build/type-check tsconfig, Jest in ESM mode, the Node 24 `engines` plus `.npmrc`, and the lockfile bumped to v3. The pre-existing scripts predate that strictness, so the rules that would force large ESM-unrelated refactors of them are disabled and those files are Prettier-ignored to keep the diff clean; only the small refactors the kept rules require (`node:` prefixes, named constants, `type`-only specifiers) are applied, with unit tests for `ein` and `csv` covering the parsing the ESM switch touched. Generated-by: GLM-5.2
6f9b24b to
51c31ee
Compare
bickelj
left a comment
There was a problem hiding this comment.
I think there are two things to do here:
- Address the review feedback regarding removal of an md file and renaming another file, do this as amendments to the existing commit(s).
- A new third commit on this branch that enables the linting rules that the service repository enforces, along with all the updates needed to the code to pass those rules.
| !config.example.json | ||
|
|
||
| # Conversion notes (local working doc, not for the repo) | ||
| CONVERT_CJS_TO_ESM.md |
There was a problem hiding this comment.
Excluding this one-off local file from everyone's repo is unnecessary and should be removed.
| standalone/ | ||
|
|
||
| # Conversion notes (untracked working doc): | ||
| CONVERT_CJS_TO_ESM.md |
There was a problem hiding this comment.
Excluding this one-off local file from everyone's repo is unnecessary and should be removed. (I removed it locally too)
| # overrides in eslint.config.mjs. New code (unit tests) and config files remain | ||
| # prettier-enforced. | ||
| # Authored by GLM-5.2. | ||
| src/candid.ts |
There was a problem hiding this comment.
This is a big ask, but I think you should leave this as-is in this commit, but go ahead and make a new third commit where these are removed, and in this new third commit the rules in eslint.config.mjs are enabled to match the rules in the service repository, and then all the code that needs to be adjusted to follow the rules also should be updated in this third commit.
| // simplification, and the await-in-loop directive pair). Those refactors are | ||
| // unrelated to the CommonJS->ESM conversion and would inject large, noisy | ||
| // diffs (and pollute future `git blame`), so they are deferred to the same | ||
| // separate follow-up rather than performed in this conversion commit. The |
There was a problem hiding this comment.
See my other comment, please do make the third follow-up commit described here.
| "lint:eslint": "eslint ./src --max-warnings=0", | ||
| "lint:prettier": "prettier . --check", | ||
| "lint:tsc": "tsc --noEmit -p tsconfig.dev.json", | ||
| "start": "node --import ./register-ts-node-esm.mjs src/index.ts", |
There was a problem hiding this comment.
Before making the third commit mentioned elsewhere, can you please amend this commit to rename register-ts-node-esm.mjs to a more concise filename without losing much clarity? It seems like a mouthful to repeat here in the package.json on every command that needs it.
This branch moves
data-scriptsfrom CommonJS to ES modules, in two reviewable commits, and then aligns its tooling with theservicerepository. Authored by GLM-5.2.Why
data-scriptspredates the shared, stricter tooling standardized in theservicerepository. Converting it to ESM in one step, then aligning to that tooling in a second step, keeps each change small and reviewable and lets the ESM conversion stand on its own.Commit 1 — Convert project to ES modules
Minimal change required by ESM only:
"type": "module", so Node resolves.jsfiles as ESM. The already-presentnodenextmodule setting then requires explicit.jssuffixes on relative imports, and running the scripts fromsrc/needs a loader mapping those suffixes back to their.tssource.ts-nodeESM register hook the dev scripts now import, and the.jssuffixes on relative imports.tsconfig.json, since they already usenodenextand still lint the ESM source.Commit 2 — Align tooling with the
servicerepositoryBrings
data-scriptsin line so both repos lint, format, type-check, and test the same way:eslint-config-love; Prettier; split build/type-checktsconfig; Jest in ESM mode; Node 24engines;.npmrc; lockfile bumped to v3.node:prefixes, named constants,type-only specifiers) are applied, with unit tests foreinandcsvcovering the parsing the ESM switch touched.Verification
npm test— 2 suites, 9 tests passed.npm run lint—eslint ./src --max-warnings=0,prettier --check, andtsc --noEmitall clean.main; the pre-existing scripts are Prettier-ignored to avoid polluting futuregit blame.Generated-by: GLM-5.2