You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore(*): migrate to TypeScript, bump to v1.0.0 (#677)
* chore(*): migrate to TypeScript, bump to v1.0.0
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>
* fix(ci): build packages in dependency order, exclude e2e from licchk
- 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>
* fix(ts): satisfy ESLint prefer-const and no-unused-vars
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>
* fix(ci): build packages from root before webpacking UMD bundles in e2e 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>
* fix(webpack): silence "Module not found: vm" warnings in template/transform 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>
* docs(transform): regenerate transformations diagram
Signed-off-by: dselman <danscode@selman.org>
---------
Signed-off-by: dselman <danscode@selman.org>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# GitHub Copilot Instructions for Markdown-Transform
2
2
3
-
This repository is **Accord Project markdown-transform** — a JavaScript npm-workspaces monorepo for parsing and transforming Markdown, CommonMark, CiceroMark, and TemplateMark.
3
+
This repository is **Accord Project markdown-transform** — a TypeScript npm-workspaces monorepo for parsing and transforming Markdown, CommonMark, CiceroMark, and TemplateMark.
- Linting: ESLint (`eslint:recommended` + strict local rules)
11
-
- Testing: Jest (most packages), Mocha (notably `packages/markdown-transform`)
12
-
- CI: GitHub Actions matrix on Ubuntu, macOS, and Windows
9
+
- Language: **TypeScript** (target `ES2020`, `module: commonjs`). Source lives in `packages/*/src/`; compiled `.js` + `.d.ts` are emitted to `packages/*/lib/`.
10
+
- Build: `tsc` per package (config extends `tsconfig.base.json`).
11
+
- Linting: ESLint with `@typescript-eslint` (4-space indent, single quotes, semicolons).
12
+
- Unit testing: **Jest 29 + ts-jest** across every package. The legacy mocha+chai suites were removed during the TS migration.
13
+
- Browser E2E: **Playwright** under `e2e/` exercises the UMD bundles in headless Chromium.
14
+
- Bundling: `webpack 5` produces UMD bundles for `markdown-html`, `markdown-template`, `markdown-transform` (the three user-facing entry points). The other packages are CommonJS library deps consumed via bundlers.
15
+
- CI: GitHub Actions matrix on Ubuntu, macOS, and Windows for unit tests; Ubuntu-only for Playwright e2e.
13
16
14
17
## Repository layout
15
18
16
-
- Root workspace packages live under `packages/`
17
-
- Primary packages include:
19
+
-`packages/` — eight publishable packages:
18
20
-`markdown-common`
19
21
-`markdown-cicero`
20
-
-`markdown-template`
21
-
-`markdown-html`
22
+
-`markdown-template`*(also UMD)*
23
+
-`markdown-html`*(also UMD)*
22
24
-`markdown-it-cicero`
23
25
-`markdown-it-template`
24
26
-`markdown-cli`
25
-
-`markdown-transform`
26
-
- Utility scripts are under `scripts/`
27
+
-`markdown-transform`*(umbrella, also UMD)*
28
+
-`e2e/` — browser end-to-end tests (Playwright). Not published.
29
+
-`scripts/` — repo-level utilities (model generation, version bumping, coverage aggregation).
30
+
-`tsconfig.base.json` — shared compiler options inherited by every package.
31
+
32
+
Concerto models for CommonMark/CiceroMark/TemplateMark are downloaded by `scripts/external/getExternalModels.js` (run via `npm run models:get` / triggered as `postinstall`) and emitted as TS into `packages/markdown-common/src/externalModels/`. Treat those files as generated.
27
33
28
34
## Non-negotiable contribution requirements
29
35
@@ -35,31 +41,32 @@ This repository is **Accord Project markdown-transform** — a JavaScript npm-wo
35
41
- Examples seen in this repo:
36
42
-`fix: update broken CI badge to use GitHub Actions workflow URL`
37
43
-`chore(deps): update package dependencies`
38
-
-`chore(actions): publish v0.16.25 to npm`
44
+
-`chore(actions): publish v1.0.0 to npm`
39
45
40
46
3.**Do not skip tests for behavior changes**
41
-
- Add or update unit tests when changing logic.
47
+
- Add or update unit tests when changing logic; add a Playwright e2e test if the change affects the browser bundle surface.
42
48
43
49
## Coding standards (repo-specific)
44
50
45
-
- Use **4-space indentation**.
46
-
- Use **single quotes**.
47
-
- Use **semicolons**.
48
-
- Avoid `var`; use `const`/`let`.
49
-
- Keep braces for control flow (`curly` rule).
50
-
- Keep strict equality (`eqeqeq`).
51
-
- Add JSDoc for classes, methods, and function declarations (`require-jsdoc`).
51
+
- TypeScript only for new code. Avoid reintroducing `.js` files in `src/`.
- The TS config is pragmatic — `strict: false`, `noImplicitAny: false` — so visitor/AST code uses `any` liberally. That is intentional: don't tighten types in unrelated files while fixing something else.
55
+
- Don't add JSDoc that simply restates the function signature; reserve comments for non-obvious *why*.
3. If needed for coverage diagnostics: `npm run coverage`
62
+
1.`npm run build` — runs `tsc` per workspace (also rebuilds before tests via each package's `pretest`).
63
+
2.`npm test` — runs the full Jest suite across every package.
64
+
3.`npm run -w markdown-transform-e2e test` — Playwright browser tests; only needed if you changed source that ends up in a UMD bundle.
65
+
4.`npm run coverage` — coverage aggregation (only if investigating coverage).
66
+
67
+
For package-level iteration, `cd packages/<name>` and run `npm run build`, `npm test`, etc. directly. For the umbrella package, also run `npm run webpack` after `npm run build` to refresh the UMD bundle.
61
68
62
-
For package-level iteration, run the package scripts directly inside the package folder (for example lint/test in `packages/markdown-common` or `packages/markdown-transform`).
69
+
When migrating Concerto: `@accordproject/concerto-core` is on **v4**. `new ModelManager({ strict: true })` is no longer valid — drop the option, don't cast to `any`. The model manager defaults are equivalent in v4.
63
70
64
71
## Dependency management rules (critical)
65
72
@@ -73,7 +80,7 @@ These are based on merged PR review feedback in this repository:
73
80
- If downgrading is required, explain why in PR description and comments.
74
81
75
82
3.**Avoid adding new dependencies without clear rationale**
76
-
- Reviewers repeatedly asked “Why the new deps?” across multiple package manifests.
83
+
- Reviewers repeatedly asked "Why the new deps?" across multiple package manifests.
77
84
- Prefer updating existing dependencies over adding new ones.
78
85
79
86
4.**For core Accord dependencies, prefer exact versions when the repo already pins exact versions**
@@ -83,6 +90,15 @@ These are based on merged PR review feedback in this repository:
83
90
5.**Keep workspace dependency versions consistent across packages**
84
91
- If bumping a shared dependency, align all affected package manifests and lockfiles in one change.
85
92
93
+
6.**Browser polyfills only when strictly needed**
94
+
- The webpack configs use `webpack.ProvidePlugin({ process: 'process/browser' })` and `resolve.alias = { jsdom: false }` to keep UMD bundles slim. Don't add Node polyfills unless a real test fails without them.
95
+
96
+
## Publishing & npm packages
97
+
98
+
-`package.json``files` field for every publishable package is `["lib"]` (or `["lib", "umd"]` for the three UMD packages). `src/`, tests, snapshots, jest config, eslint config, and tsconfig stay out of the tarball.
99
+
-`main: "lib/index.js"`, `types: "lib/index.d.ts"`. The three UMD packages also set `browser: "umd/markdown-X.js"` so bundlers serving browser targets pick the UMD bundle automatically.
100
+
- Source maps (`*.js.map`) **are** shipped — keep `sourceMap: true` in `tsconfig.base.json` so consumer stack traces stay useful.
101
+
86
102
## AI review behavior (adapted from best-practice guidance)
87
103
88
104
Copilot suggestions should follow a **human-in-the-loop**, high-signal workflow:
@@ -100,7 +116,7 @@ Copilot suggestions should follow a **human-in-the-loop**, high-signal workflow:
100
116
- Do not trade security for convenience.
101
117
102
118
4.**Continuous learning loop**
103
-
- If a review pattern repeats (e.g., “why new dependency?”, “why downgrade?”), treat it as a standing rule for future changes.
119
+
- If a review pattern repeats (e.g., "why new dependency?", "why downgrade?"), treat it as a standing rule for future changes.
104
120
- Prefer repository-established patterns over generic defaults.
105
121
106
122
5.**Human validation remains required**
@@ -111,18 +127,21 @@ Copilot suggestions should follow a **human-in-the-loop**, high-signal workflow:
111
127
Before proposing a PR-ready change:
112
128
113
129
-[ ] Change scope is minimal and focused
114
-
-[ ] New/updated behavior has tests
130
+
-[ ] New/updated behavior has tests (unit and, where relevant, Playwright e2e)
115
131
-[ ] Lint/build/tests pass
132
+
-[ ]`npm pack --dry-run` for any package whose contents changed shows only `lib/` (+ optional `umd/`) — no tests, snapshots, or configs leaking
116
133
-[ ] Dependency changes are justified and minimal
117
134
-[ ] No accidental downgrades or unnecessary added packages
118
135
-[ ] Commit(s) use DCO sign-off
119
136
-[ ] PR description clearly explains **why** the change is needed
120
137
121
138
## Common pitfalls in this repo
122
139
140
+
- Mixing `.js` and `.ts` in `src/` — the source tree is TypeScript only.
141
+
- Forgetting to rebuild UMD bundles (`npm run webpack -w …`) after source changes; the Playwright e2e tests will then test stale code.
142
+
- Adding broad type tightening (`noImplicitAny`, `strict`) in unrelated files while fixing a small bug — out of scope, expand `any` only where the change is needed.
123
143
- Adding many dependency changes in one sweep without explaining each one.
124
144
- Switching from exact to ranged versions for core dependencies without team agreement.
125
-
- Introducing dependency downgrades as side effects of automated tooling.
126
-
- Making large unrelated edits while addressing a small issue.
145
+
- Re-introducing `npm install`-time `prepare`/`build` scripts. Build is a separate explicit step now (`npm run build`), keeping `npm install` fast and resilient to broken intermediate states.
127
146
128
147
When in doubt, prefer small, explicit, well-tested changes that match existing package patterns.
@@ -37,23 +39,23 @@ Top level repository (markdown-transform), with sub packages. Each sub-package i
37
39
38
40
The CommonMark DOM is a model for the elements of CommonMark (the specification for markdown text), expressed as a [Concerto schema](https://github.com/accordproject/concerto), and serialized as a JSON graph.
39
41
40
-
The schema is defined here: https://models.accordproject.org/markdown/commonmark@0.2.0.html
42
+
The schema is defined here: https://models.accordproject.org/markdown/commonmark@0.5.0.html
41
43
42
44
### CiceroMark DOM
43
45
44
46
CiceroMark defines markdown documents with embedded clauses, where each clause is an instance of a template, specified using TemplateMark.
45
47
46
-
The CiceroMark DOM extends the CommonMark DOM, defining nodes for `Clause`, `Variable` and `Formula`etc.
48
+
The CiceroMark DOM extends the CommonMark DOM, defining nodes for `Clause`, `Variable`, `FormattedVariable`, `EnumVariable`, `Conditional`, `Optional`, `Formula`and `ListBlock`.
47
49
48
-
The schema is defined here: https://models.accordproject.org/markdown/ciceromark@0.3.0.html
50
+
The schema is defined here: https://models.accordproject.org/markdown/ciceromark@0.6.0.html
49
51
50
52
### TemplateMark DOM
51
53
52
54
TemplateMark defines markdown documents with syntax for embedded variables, optional blocks, formulas etc. It is used to define Accord Project templates.
53
55
54
-
The TemplateMark DOM extends the CommonMark DOM, defining nodes for `ClauseDefinition`, `VariableDefinition` and `ForumulaDefinition` etc.
56
+
The TemplateMark DOM extends the CommonMark DOM, defining nodes for `ClauseDefinition`, `ContractDefinition`, `VariableDefinition`, `FormattedVariableDefinition`, `EnumVariableDefinition`, `ConditionalDefinition`, `OptionalDefinition`, `WithDefinition`, `JoinDefinition`, `ListBlockDefinition` and `FormulaDefinition`.
55
57
56
-
The schema is defined here: https://models.accordproject.org/markdown/templatemark.html
58
+
The schema is defined here: https://models.accordproject.org/markdown/templatemark@0.5.0.html
57
59
58
60
## Installation
59
61
@@ -76,13 +78,14 @@ markus --help
76
78
npm install
77
79
```
78
80
79
-
Then run:
81
+
Then build all packages and run their tests:
80
82
81
83
```
84
+
npm run build
82
85
npm run test
83
86
```
84
87
85
-
This command uses npm workspaces to run the tests for each package in the monorepo.
88
+
These commands use npm workspaces. `build` runs `tsc`for each package, producing JavaScript and `.d.ts` declarations into `packages/*/lib/`. `test` runs Jest. Requires Node 22 or later.
[Playwright](https://playwright.dev) tests that load the UMD bundles for `markdown-html`, `markdown-template` and `markdown-transform` into a real headless Chromium and call the public API. These tests exist to catch packaging/bundling regressions that unit tests miss — for example, accidentally pulling Node-only modules like `jsdom` into the browser bundle.
4
+
5
+
## Run
6
+
7
+
From the repository root:
8
+
9
+
```bash
10
+
npm install --workspaces
11
+
npm run -w markdown-transform-e2e test
12
+
```
13
+
14
+
`npm test` from the e2e directory runs `pretest` first, which:
15
+
1. Builds each TS package (`tsc`)
16
+
2. Builds each UMD bundle (`webpack`)
17
+
3. Installs the Chromium browser used by Playwright (cached after first run)
18
+
19
+
## What's covered
20
+
21
+
| Spec | Asserts |
22
+
|------|---------|
23
+
|`markdown-html.spec.ts`|`HtmlTransformer` exported on the global; `toHtml`/`toCiceroMark` work using the native `DOMParser` (jsdom is **not** in the browser bundle) |
24
+
|`markdown-template.spec.ts`|`TemplateMarkTransformer` exported; `toTokens` and `normalizeNLs` work |
25
+
|`markdown-transform.spec.ts`|`transform`, `formatDescriptor`, `generateTransformationDiagram`, `TransformEngine` exported; markdown → commonmark and markdown → html transformations succeed |
26
+
27
+
## Adding a test
28
+
29
+
Each UMD bundle exports its API onto `window['<package-name>']` (e.g. `window['markdown-html']`). Spec pattern:
0 commit comments