Skip to content

Generator

@typemf/generator turns an Ecore model (a .ecore file) into code. The built-in typescript template set generates TypeScript for @typemf/core: an interface and an implementation class per class, a package and a factory, a visitor and type guards. See What gets generated.

Annotations in the .ecore file add documentation, method bodies and type mappings to the generated code; see Annotations.

Terminal window
npm install --save-dev @typemf/generator

A config file says what to generate. Name it <name>.typemf-generator.json, for example library.typemf-generator.json; VS Code then opens it in the generator editor.

library.typemf-generator.json
{
"ecoreFile": "./model/library.ecore",
"outputDir": "./src/generated",
"templateSet": "typescript",
"options": {}
}
Field Required Meaning
ecoreFile yes The .ecore file, relative to the config file.
outputDir yes Where the generated files go, relative to the config file. Created if missing.
templateSet yes The template set to generate with.
options no Options of the template set. Checked against its options schema; an unknown option is an error.

One config file means one model, one output folder and one template set. For several models or several target languages, write one config file each.

Terminal window
npx typemf-generate library.typemf-generator.json
Terminal window
npx typemf-generate [config file] [--template-set <package folder>]... [--no-discover]
  • config file: without it, the CLI reads ./typemf-generator.json.
  • --template-set <package folder>: registers the template sets of a package folder (a folder with a package.json). Repeatable, also written --template-set=<folder>. Wins over a discovered set of the same name. The folder must declare at least one template set.
  • --no-discover: don’t look for template sets among the project’s dependencies.

On success the CLI prints typemf-generate: wrote N file(s) to <outputDir>. On failure it prints typemf-generate: <message> and exits with code 1. It overwrites existing files without asking.

The TypeMF Instance Editor extension opens *.typemf-generator.json and typemf-generator.json files in a form.

  • Ecore file and Output folder: type a path or pick one with Browse…. Picked paths are stored relative to the config file.
  • Template set: a list of the built-in set, the sets of the project’s dependencies, and those of the folders in the setting typemf.generator.templateSetPackages. Add package… picks a package folder and adds it to that setting. A set that isn’t found is marked (not found).
  • Options: a form built from the template set’s options schema. For typescript, the keys of package-imports and type-imports are suggested from the model. Options a form can’t show are edited as JSON.
  • Generate: generates from the current content of the file, saved or not. If existing files would change, it asks before overwriting them. A template set that runs code (a hooks module) generates only in a trusted workspace.
  • Edit as text: opens the file in the text editor, with completion and validation of the fields and of the typescript options.

The form edits the text of the file, so undo, save and changes from outside work as for any text file. If the file isn’t valid JSON, the form shows the error and offers only Edit as text.

typescript is built in. Other template sets come in npm packages: install the package as a dependency of your project and put the set’s name in templateSet. The CLI and the editor find it in the dependencies, devDependencies and optionalDependencies of the closest package.json above the config file.

If two dependencies declare a set of the same name, generating with that name fails and the error names both packages. Choose one with --template-set <package folder>. Clashes between other names don’t matter.

A package declares its template sets in its package.json:

package.json
"typemf": {
"templateSets": [
{
"name": "java",
"description": "Java code",
"templates": "./templates",
"optionsSchema": "./options.schema.json",
"module": "./dist/hooks.js"
}
]
}
Field Required Meaning
name yes What templateSet in a config file says.
description no One line, shown in the editor.
templates yes Folder of Nunjucks templates with the entry point main.njk.
optionsSchema no JSON Schema file for options. Used to check the options and to build the editor’s form. Without it, any options are accepted.
module no JavaScript module exporting any of the hooks validate, configureEnvironment and postProcessFile.

Paths are relative to the package. The hooks module is the only code of the package that is run; finding and listing template sets runs none. The hooks are described by the TemplateSet interface of @typemf/generator.

Programs can register template sets with registerTemplateSet, or with registerTemplateSets, which does what the CLI does. listTemplateSets lists the registered ones.

Option Type Meaning
package-imports object, nsURI → string Where the generated code of another package is. See below.
type-imports object, <nsURI>#<name> → import Which symbol to import for a data type. Overrides the import annotation of the data type.
generate-ecore boolean The model is Ecore itself; generates the metamodel of @typemf/core.

An entry of type-imports has type, the symbol to import; from, the module other packages import it from; and internal-from, where the generated package itself imports it from (relative to its root when it starts with ./; defaults to from):

"options": {
"type-imports": {
"https://example.com/shapes#Color": {
"type": "Color",
"from": "@example/colors"
}
}
}

A .ecore file can use classifiers of another .ecore file, for example href="shapes.ecore#//Shape". The generator loads the other file but doesn’t generate it. Generate it with its own config file, and say in package-imports where its code is, by nsURI:

model/
shapes.ecore nsURI https://example.com/shapes
drawing.ecore uses classifiers of shapes.ecore
shapes.typemf-generator.json
drawing.typemf-generator.json
shapes.typemf-generator.json
{
"ecoreFile": "./model/shapes.ecore",
"outputDir": "./src/generated/shapes",
"templateSet": "typescript"
}
drawing.typemf-generator.json
{
"ecoreFile": "./model/drawing.ecore",
"outputDir": "./src/generated/drawing",
"templateSet": "typescript",
"options": {
"package-imports": {
"https://example.com/shapes": "../shapes"
}
}
}
Terminal window
npx typemf-generate shapes.typemf-generator.json
npx typemf-generate drawing.typemf-generator.json

A value starting with ./ or ../ is the folder of the other package’s generated code, relative to outputDir. Any other value is a module name that exports the package’s types and its PackageImpl. Classifiers of Ecore need no entry. Supertypes from another package are not supported yet.