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.
npm install --save-dev @typemf/generatorThe config file
Section titled “The config file”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.
{ "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.
On the command line
Section titled “On the command line”npx typemf-generate library.typemf-generator.jsonnpx 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 apackage.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.
In VS Code
Section titled “In VS Code”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 ofpackage-importsandtype-importsare 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
typescriptoptions.
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.
Template sets
Section titled “Template sets”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.
Writing a template set
Section titled “Writing a template set”A package declares its template sets in its 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.
Options of the typescript template set
Section titled “Options of the typescript template set”| 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" } }}Models across several files
Section titled “Models across several files”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.ecoreshapes.typemf-generator.jsondrawing.typemf-generator.json{ "ecoreFile": "./model/shapes.ecore", "outputDir": "./src/generated/shapes", "templateSet": "typescript"}{ "ecoreFile": "./model/drawing.ecore", "outputDir": "./src/generated/drawing", "templateSet": "typescript", "options": { "package-imports": { "https://example.com/shapes": "../shapes" } }}npx typemf-generate shapes.typemf-generator.jsonnpx typemf-generate drawing.typemf-generator.jsonA 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.