Generates .ts
files for a CDS model to receive code completion in VS Code.
This project is available as @cap-js/cds-typer
as NPM package.
The type generator can either be used as a standalone tool, or as part of of the CDS VSCode-Extension.
Assuming you have the following CDS project structure:
/home/
├── mybookshop/
│ ├── db/
│ │ └── schema.cds
│ ├── srv/
│ │ └── service.js
a typical workflow to generate types for your CDS project could look something like this:
npx @cap-js/cds-typer /home/mybookshop/db/schema.cds --outputDirectory /home/mybookshop/@types
You would then end up with a directory @types
, which contains your entities and their accompanying types in a directory structure. The directory structure directly reflects the namespaces you have defined your entities in. They have to be imported in any JavaScript-based service handlers you want to have type support in and can replace calls to cds.entities(...)
:
// srv/service.js
const { Books } = require('my.bookshop')
becomes
// srv/service.js
const { Books } = require('../@types/mybookshop')
From that point on you should receive code completion from the type system for Books
.
Note: the above command generates types for the model contained within the mentioned schema.cds
file. If you have multiple .cds
files that are included via using
statements by schema.cds
, then those files will also be included in the type generation process. If you have .cds
files that are not in some way included in schema.cds
, you have to explicitly pass those as positional argument as well, if you want types for them.
cds-typer comes with rudimentary CLI support and a few command line options:
--help
: prints all available parameters.--outputDirectory
: specifies the root directory where all generated files should be put. Defaults to the CWD.--jsConfigPath
: specifies the path to thejsconfig.json
file to generate. Usually your project's root directory. If specified, a config file is created that restricts the usage of types even further:
// generated .ts file
class Book {
title: string;
}
// some hook in your service
SELECT(Books, b => {
b.title // 👍 no problem, property exists
b.numberOfPages // ❌ property does not exist
})
With the generated config in place, the language server will display an error, telling you that numberOfPages
does not exist in this context. Without the config it would just infer it as any
.
--loglevel
: minimum log level that should be printed. Defaults toNONE
. Available log levels roughly follow Microsoft's dotnet log levels:
TRACE
DEBUG
INFO
WARNING
ERROR
CRITICAL
NONE
The utility expects (at least) one path to a .cds
file as positional parameter which serves as entry point to the model in question, e.g.:
npx @cap-js/cds-typer ./path/to/my/model/model.cds --outputDirectory /tmp/
Note that you can also pass multiple paths or "*"
as glob pattern (with quotes to circumvent expansion by the shell). This passes the pattern on to the compiler where the regular resolve strategy is used.
Installing the CDS VSCode Extension also adds support for generating types for your model from within VSCode. Adding the appropriate facet to your project via cds add typer
(and installing the added dependencies thereafter) allows you to simply hit save on any .cds
file that is part of your model to trigger the generation process.
The main API for using cds-typer within another project is contained in compile.js
, specifically:
compileFromFile(…)
to parse a.cds
file. This involves compiling it to CSN first.compileFromCSN(…)
to directly compile from CSN object. This is useful when you already have your CSN available as part of a tool chain.⚠️ WARNING: the application ofcdstyper
may be impure, meaning that it could alter the provided CSN. If you use the typer this way, you may want to apply it as last step of your tool chain.
While CDS encourages the use of plural form for defined entities, their OOP equivalent classes are usually named in singular. cds-typer automatically transforms entity names to singular and adds the plural form for arrays:
entity Books : cuid {
…
}
becomes
class Book {
…
}
class Books extends Array<Book> {}
If you need to customise the singular or plural form, or if your entities are already in singular form, you can do so using annotations:
@singular: 'Mouse'
entity Mice {}
@plural: 'SomeListList'
entity SomeList {}
results in
class Mouse { … }
class Mice extends Array<Mouse> { … }
class SomeList { … }
class SomeListList extends Array<SomeList> { … }
This project is inspired by the existing cds2types, but differs in a few aspects:
Instead of one monolithic .d.ts
file containing all entities in nested namespaces, multiple files are generated where each namespace is represented by a directory structure. This facilicates simpler imports in a more Java-esque style:
const types = require('./cds2types/compiled.d.ts')
console.log(types.sap.cap.bookshop.Books) // a class
becomes
const { Books } = require('./cds-typer/sap/cap/bookshop')
console.log(Books) // the same class
Generated code is usable from within plain Javascript projects. The code generated by cds2types would represent each cds-entity as an interface, which are not visible to Javascript projects. cds-typer uses classes instead.
cds2types takes a detour to create a Typescript AST first and then print out the formatted source files. cds-typer directly walks the linked CSN and creates strings on the fly. Also, file operations are async
. These two changes speed up cds-typer by around one to two orders of magnitude compared to cds2types.
cds-typer tries to keep its dependency footprint as small as possible. Libraries like typescript
are only needed as dev dependencies.
This project is open to feature requests/suggestions, bug reports etc. via GitHub issues. Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its Code of Conduct at all times.
Copyright 2022-2022 SAP SE or an SAP affiliate company and cds-typer contributors. Please see our LICENSE for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available via the REUSE tool.