chore(*): migrate to TypeScript, bump to v1.0.0#677
Conversation
Convert the entire monorepo from JavaScript (CommonJS + JSDoc-emitted .d.ts) to TypeScript source compiled to .js + .d.ts. Per package: - Move sources from lib/ (or src/) JavaScript to src/*.ts. tsc emits to lib/ during build (now gitignored). - Drop hand-written types/ in favour of declarations generated by tsc. - Remove babel toolchain (@babel/cli, @babel/preset-env, babel-loader, babel-plugin-istanbul, tsd-jsdoc, jsdoc, .babelrc, jsdoc.json). - Add per-package tsconfig.json extending the new tsconfig.base.json, plus tsconfig.test.json for ts-jest, jest.config.js using ts-jest preset, and .eslintrc.cjs with @typescript-eslint. - package.json: main/types/typings point at lib/; files: ["lib"] (or ["lib","umd"]) so published tarballs contain only the build output — no tests, snapshots, or configs leak. Test runners: - markdown-template, markdown-transform and markdown-cli moved off mocha+chai onto jest+ts-jest. Snapshots preserved. - All 1,860 unit tests pass across the 8 packages. External models: - scripts/external/Models.hbs and getExternalModels.js now generate TypeScript modules into packages/markdown-common/src/externalModels/ (previously .js into lib/externalModels/). Webpack UMD bundles (markdown-html, markdown-template, markdown-transform): - Swap babel-loader for ts-loader; entry now ./src/index.ts. - Add `webpack.ProvidePlugin({ process: 'process/browser' })` (webpack 5 no longer auto-polyfills) and `resolve.alias = { jsdom: false }` in the markdown-html config to keep the bundle slim (4.7 MB → 1.12 MB). - Browser entry point on each UMD package's package.json points at umd/markdown-X.js so bundlers automatically prefer it. Browser end-to-end tests: - New e2e/ workspace using Playwright (Chromium) loads each UMD bundle via addScriptTag and exercises public APIs in a real browser. 9 tests pass locally. - New build.yml job runs the Playwright suite on ubuntu-latest, with the browser binary cached across runs. Concerto v3 → v4: - Bump @accordproject/concerto-core to ^4.1.3 across the workspace, @accordproject/concerto-cto to ^4.1.3 in markdown-template, @accordproject/concerto-util to ^4.1.4 in markdown-cli. - Drop the now-defunct `{ strict: true }` ModelManagerOptions argument (the option was removed in v4; the default behaviour is equivalent). Misc: - Bump every package.json version to 1.0.0. - Update READMEs across all 9 modules (root + 8 packages) for accuracy: fix outdated schema URLs, correct format names, drop "in progress…" placeholders, add TypeScript usage examples, remove unsupported ModelLoader signature, list real supported format names in CLI docs. - Refresh .github/copilot-instructions.md to reflect the new toolchain (TS, jest+ts-jest, playwright, no babel/jsdoc). - Remove root jsdoc.json (no longer referenced by any script). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: dselman <danscode@selman.org>
- Root `build` script: previous `npm run build --workspaces` ran tsc per workspace in an undefined order. On a clean CI checkout this failed because e.g. `markdown-cicero` was compiled before `markdown-common`'s `lib/` (and thus its `.d.ts`) existed, surfacing as `TS2307: Cannot find module '@accordproject/markdown-common'`. Replaced with an explicit topological sequence: common → markdown-it-* → cicero → html, template → transform → cli. - License check: the root `license-check-and-add-config` was scanning the new `e2e/` workspace and the `js|ergo|cto` license format key predated the TypeScript migration. Added `e2e` to `exact_paths` so the e2e fixtures don't trip the root check, and renamed the format key to `ts|tsx|js|cto` (drop legacy `ergo`). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: dselman <danscode@selman.org>
The TS migration accidentally left several `let` declarations that are only ever assigned once — prefer-const flags these. Same for two test fixture constants that became dead after a refactor. CI lint surfaced them on the first non-local build; local development missed them because `pretest` (lint) was skipped when iterating with `npx jest` directly. - packages/markdown-it-template/src/template_block.ts: convert the block_open / attrs / block_name / markup / old_parent / old_line_max pre-declarations to const-at-assignment-site. - packages/markdown-it-template/src/template_inline.ts: const max. - Mirror both changes in markdown-it-cicero/src/cicero_block.ts and cicero_inline.ts. - packages/markdown-cli/src/cli.test.ts: drop the unused parameters scratch variable and the unused acceptanceGrammarFile constant. The remaining test cases pass parameters inline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: dselman <danscode@selman.org>
…e job The e2e job's `Build packages and UMD bundles` step relied on `e2e`'s `prebuild:bundles` to build the three UMD packages, but those packages depend on `markdown-common` / `markdown-cicero` which weren't being built first — surfacing as TS2307 the same way the unit tests originally did. Split the e2e workflow into two steps: - `Build packages (dep order)` — runs the root `build` script, which topo-sorts every workspace via the previous CI fix. - `Build UMD bundles` — only the three webpack steps remain in `e2e`'s `build:bundles`. Drop `prebuild:bundles` from `e2e/package.json` since the root build now covers it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: dselman <danscode@selman.org>
…nsform UMD webpack 5 stopped auto-polyfilling Node built-ins. crypto-browserify pulls in asn1.js which statically references `vm` on a code path that never runs in the browser, producing noisy "Can't resolve 'vm'" warnings during webpack of `markdown-template` and `markdown-transform`. Explicitly set `vm: false` in `resolve.fallback` so webpack treats the import as an empty module — same trick the surrounding `fs`/`tls`/etc. entries already use. Behaviour is unchanged at runtime; we just stop the build output from emitting BREAKING-CHANGE-style warnings that look alarming but are harmless. markdown-html already polyfills `vm` via `vm-browserify`; no change needed there. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: dselman <danscode@selman.org>
Signed-off-by: dselman <danscode@selman.org>
mttrbrts
left a comment
There was a problem hiding this comment.
Three inline notes from code review.
| "forceConsistentCasingInFileNames": true, | ||
| "skipLibCheck": true, | ||
| "strict": false, | ||
| "noImplicitAny": false, |
There was a problem hiding this comment.
Type rigor regression. strict, noImplicitAny, and strictNullChecks are all false, and ~297 : any annotations appear across 49 non-test source files. This substantially walks back #669 ('replace any with concrete types') -- downstream consumers now receive weaker .d.ts declarations than before the migration. Pragmatic for a migration of this size, but worth a follow-up tracking issue to ratchet strict back on incrementally once things settle.
| "name": "@accordproject/markdown-cicero", | ||
| "version": "0.16.25", | ||
| "version": "1.0.0", | ||
| "description": "A framework for transforming markdown", |
There was a problem hiding this comment.
Concerto version inconsistency. The root package.json and the PR description both target ^4.1.3, but markdown-cicero pins ^4.1.2 in both devDependencies and peerDependencies. The caret range means this resolves harmlessly at install time, but worth aligning to ^4.1.3 for consistency across the workspace.
| fs.writeFileSync(buildModelsJs,result); | ||
| const buildModelsTs = path.join(outDir, context.name + '.ts'); | ||
| console.log('Creating: ' + buildModelsTs); | ||
| fs.writeFileSync(buildModelsTs, result); | ||
| } |
There was a problem hiding this comment.
External models cause working-tree churn. getExternalModels.js now writes generated .ts files into packages/markdown-common/src/externalModels/, and those files are tracked in git. Because postinstall -> models:get regenerates them on every npm ci, contributors will see spurious diffs whenever the template or fetched models change. Consider either: (a) gitignoring the generated externalModels/ dir and adding a prebuild step to regenerate, or (b) marking the generated files with a // @generated header so reviewers know not to edit them by hand.
| "resolveJsonModule": true, | ||
| "forceConsistentCasingInFileNames": true, | ||
| "skipLibCheck": true, | ||
| "strict": false, |
There was a problem hiding this comment.
Type rigor regression. strict, noImplicitAny, and strictNullChecks are all false, and ~297 : any annotations appear across 49 non-test source files. This substantially walks back #669 ('replace any with concrete types') -- downstream consumers now receive weaker .d.ts declarations than before the migration. Pragmatic for a migration of this size, but worth a follow-up tracking issue to ratchet strict back on incrementally once things settle.
| @@ -46,11 +46,17 @@ | |||
| "homepage": "https://github.com/accordproject/markdown-transform", | |||
| "devDependencies": { | |||
| "@accordproject/concerto-core": "^4.1.2", | |||
There was a problem hiding this comment.
Concerto version inconsistency. The root package.json and the PR description both target ^4.1.3, but markdown-cicero pins ^4.1.2 here and in peerDependencies. The caret range means this resolves harmlessly at install time, but worth aligning to ^4.1.3 for consistency across the workspace.
| fs.writeFileSync(buildModelsJs,result); | ||
| const buildModelsTs = path.join(outDir, context.name + '.ts'); | ||
| console.log('Creating: ' + buildModelsTs); | ||
| fs.writeFileSync(buildModelsTs, result); |
There was a problem hiding this comment.
External models cause working-tree churn. This now writes generated .ts files into packages/markdown-common/src/externalModels/, which are tracked in git. Because postinstall -> models:get regenerates them on every npm ci, contributors will see spurious diffs whenever the template or fetched models change. Consider: (a) gitignoring the externalModels/ dir and adding a prebuild step to regenerate, or (b) marking generated files with a // @generated header so reviewers know not to edit them by hand.
mttrbrts
left a comment
There was a problem hiding this comment.
Will leave comments to your judgement
I agree we should squash the "any" but I think we get this merged first and can then make it more type safe. |
Convert the entire monorepo from JavaScript (CommonJS + JSDoc-emitted .d.ts) to TypeScript source compiled to .js + .d.ts.
Per package:
Test runners:
External models:
Webpack UMD bundles (markdown-html, markdown-template, markdown-transform):
webpack.ProvidePlugin({ process: 'process/browser' })(webpack 5 no longer auto-polyfills) andresolve.alias = { jsdom: false }in the markdown-html config to keep the bundle slim (4.7 MB → 1.12 MB).Browser end-to-end tests:
Concerto v3 → v4:
{ strict: true }ModelManagerOptions argument (the option was removed in v4; the default behaviour is equivalent).Misc:
Closes #
Changes
Flags
Screenshots or Video
Related Issues
Author Checklist
--signoffoption of git commit.mainfromfork:branchname