cedar-embeddable-editor
v2.0.9
Published
A reusable Web Component for creating and editing CEDAR metadata instances.
Maintainers
Readme
CEDAR Embeddable Editor (CEE)
The CEDAR Embeddable Editor (CEE) puts a metadata entry form inside a web application without anyone hand-writing that form. The host page supplies a template, and the CEE renders the fields the template calls for, checks what the user enters against the template's constraints, and returns the finished record as structured metadata in JSON-LD or YAML.
A template describes the metadata to collect, not the interface that collects it. It names the fields, their types and cardinalities, which of them repeat, and which draw their values from a controlled vocabulary or from an identifier authority such as ORCID or ROR. A platform can therefore adopt or revise a metadata standard by editing a template rather than by rewriting a form. The record that comes back preserves those bindings, since a controlled term carries its IRI beside its label and an authority field carries its persistent identifier.
Templates follow the model defined by CEDAR, the metadata infrastructure maintained by the Stanford Division of Computational Medicine. Rendering a form needs neither a CEDAR account nor a running CEDAR installation. The CEE ships as a single JavaScript file defining a standard Web Component, so it embeds in a plain HTML page as readily as in an Angular, React, or Ember application.
Documentation
The CEDAR Embeddable Editor documentation covers embedding the component in a page or a framework, configuring it, controlled terms and external identifiers, validation, appearance, and security.
Your First Embedded Editor assembles a working page from the bundle, one element, and a template. Templates and Metadata gives the input properties, the output properties, and the change event a host reads.
For the design rationale, the architecture, and deployments in research platforms, see Author Once, Publish Everywhere: Portable Metadata Authoring with the CEDAR Embeddable Editor, published in the Data Science Journal (2026).
Installing
Releases are published to npmjs.org as
cedar-embeddable-editor
under the latest tag, the public stable channel, so an embedder installs the
current release by name:
npm install cedar-embeddable-editorTo see which release that is, without depending on a version copied into a document that can go stale:
npm view cedar-embeddable-editor versionThe package holds cedar-embeddable-editor.js, the self-contained bundle, and
cedar-embeddable-editor.d.ts, the declarations for the element and its public
API. Copy the bundle to the application's static assets and load it with a
regular <script> tag. The bundle loads as a classic script, not as an ES
module.
Embedding
A host page needs the bundle, one <cedar-embeddable-editor> element, and a
template:
<cedar-embeddable-editor></cedar-embeddable-editor>
<script src="/assets/cedar-embeddable-editor.js"></script>
<script type="module">
const template = await (await fetch('/assets/dataset-template.json')).json();
await customElements.whenDefined('cedar-embeddable-editor');
const cee = document.querySelector('cedar-embeddable-editor');
cee.config = {
terminologyBaseUrl: 'https://terminology.metadatacenter.org/',
bridgeBaseUrl: 'https://bridge.metadatacenter.org/',
};
cee.templateObject = template;
</script>Templates, instances, and configuration are JavaScript objects, so a host assigns
them as properties rather than as attributes. Waiting for
customElements.whenDefined() guarantees the element exists. Set config before
the form is built, and assign templateObject last, which renders it. The two
service URLs are needed only for controlled-term and external-authority lookups.
Read the record back from currentMetadata as CEDAR JSON-LD, or from
currentMetadataYaml as YAML. The CEE neither submits nor stores it. The host
decides when and where a record is saved.
Your First Embedded Editor takes the same page apart step by step, and Embedding in a Framework covers Angular, React, and Ember.
Building the Web Component
One command produces the single file an embedder loads. Do not concatenate named Angular output files manually: their names, locations, and module structure change when Angular changes builders.
Build the production application, then run the browser suite against the single-file bundle it produced:
nvm use
npm run build:production
npm run test:visual:prebuiltUse Node 24.19.0, which .nvmrc, package.json and CI all specify. The build and
tests use that same version, so the distribution is produced by the toolchain
that exercises it.
Once that exact bundle is green, stage the publishable npm directory from it:
npm run package:npm:prebuiltFor a release candidate, npm run test:package performs both operations in one command: it builds
and browser-tests the production bundle, then stages and verifies the package from those exact
tested bytes.
This copies the tested bytes to
dist-npm/cedar-embeddable-editor/cedar-embeddable-editor.js, refreshes its
version, README, changelog, and package lock, and records the bundle manifest.
The command fails if the browser bundle is stale or does not match its SHA-256
digest. npm run check:npm-package can repeat the byte-for-byte verification
before npm pack or npm publish.
Testing
The complete test gate is available from the repository root:
npm run test:ciIt runs, in order:
ng lintover the sources and the ESLint configuration.- A type check of the application and the domain harness, with
stricton throughout. - The unit tests, in Node under Vitest.
- The headless domain harness with V8 coverage, and its per-directory coverage floors.
- A production build, then the Playwright suite against that bundle, in a
container: the full Chromium baseline at desktop and narrow viewport sizes,
plus focused Chromium, Firefox and WebKit compatibility checks. The container
is what makes a screenshot baseline mean the same thing on a laptop and on CI,
so the pixel budget is zero — see
visual/run-in-container.sh. - Staging the npm package from the bundle the suite just exercised, which checks the raw and gzip size budgets and verifies every staged byte against its source.
The domain corpora are checked into harness/fixtures/; running the tests does
not require cedar-artifact-library or cedar-test-artifacts checkouts.
.github/workflows/test.yml runs the same gate on every pull request and on
pushes to main and develop. Nothing is published from CI: releasing is a
separate, manual procedure.
Auditing what ships
npm run audit:prodOnly runtime dependencies reach the file an embedder downloads, so this audit is
the one that describes the shipped artifact, and it is deliberately not part of
test:ci — it can fail on a disclosure rather than on a commit, which would
break an unrelated pull request its author cannot fix.
A root npm audit also reports on development tooling that is not shipped to an
embedder. Never run npm audit fix --force here: it can replace the declared
toolchain with incompatible major versions. Review and update affected
dependencies explicitly instead.
First-time setup
The CEE resolves cedar-model-typescript-library from npmjs.org, so a sibling
checkout is not needed:
nvm use
npm ci
npm --prefix harness ciThe visual suite installs nothing here. It runs inside Playwright's own container,
which carries the browsers it drives, and installs its dependencies there against a
named volume — so it needs Docker running and no playwright install of its own.
The CEE uses Angular 22.1 and Node 24.19.0. .nvmrc, the package engines field and
CI specify the Node version.
The application bundle and the visual fixture generator each install the model library directly from npmjs.org:
"cedar-model-typescript-library": "<version>"Keep the version in the root and visual/ manifests, and both lockfiles, in
sync. The production bundle imports the root copy while the browser fixtures are
generated with the visual copy, so a mismatch means the tests and the artifact
are using different model contracts. The harness declares no separate copy; it
resolves the root installation.
Focused test commands
Use these when working on one layer:
npm run test:unit:ci # Vitest unit tests, one run
npm run test:unit:coverage # unit tests with coverage report
npm run test:domain # Vitest domain harness
npm run test:domain:coverage # domain harness with coverage report
npm run test:bundle-size # exact raw and gzip budgets for the shipped bundle
npm run test:visual # production build, fixture preparation, Playwrightnpm test runs the unit tests once, and npm run test:watch keeps them running
for interactive development. Use npm run test:ci for a complete verification.
The unit tests run in Node and do not use TestBed or Angular's JIT compiler.
Browser behavior belongs in the Playwright suite under visual/, which tests the
shipped bundle rather than the sources.
Running the Standalone Application
The CEE also runs on its own, outside any host page, which shows a change to the sources immediately in a browser.
Clone the repository
Clone this repository onto a local directory of your choice:
git clone https://github.com/metadatacenter/cedar-embeddable-editor.gitEdit configuration
Open the standalone application's configuration file, src/app/app.component.dev.ts.
This minimal configuration enables lookups through the public CEDAR services:
import type { CeeConfig } from 'cedar-embeddable-editor';
const ceeConfig: CeeConfig = {
terminologyBaseUrl: 'https://terminology.metadatacenter.org/',
bridgeBaseUrl: 'https://bridge.metadatacenter.org/',
};For a different CEDAR deployment, replace both URLs with its service URLs. See the configuration documentation for all available settings.
Build the project and start the server
Navigate to the CEE directory:
cd <...>/<clone directory>/cedar-embeddable-editor/Run these commands:
npm install ng serveIn your browser, navigate to
http://localhost:4400/. The app will automatically reload if you change any of the source files.
