CDS type generator for JavaScript
About this project
Generates .ts
files for a CDS model to receive code completion in VS Code.
Requirements and Setup
This project is available as @cds-js/cds-typer
as NPM package.
Usage
The type generator can either be used as a standalone tool, or as part of of the CDS VSCode-Extension.
Standalone CLI
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(...)
:
const { Books } = require('my.bookshop')
becomes
const { Books } = require('../@types/mybookshop')
From that point on you should receive code completion from the type system for Books
.
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 the jsconfig.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:
class Book {
title: string;
}
SELECT(Books, b => {
b.title
b.numberOfPages
})
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
.
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.
From VSCode
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.
Programmatically
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 of cdstyper
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.
Features
Plural Types
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> { … }
Relation to cds2types
This project is inspired by the existing cds2types, but differs in a few aspects:
Reworked Imports
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)
becomes
const { Books } = require('./cds-typer/sap/cap/bookshop')
console.log(Books)
Usable in Javascript Projects
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.
Faster
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.
Support, Feedback, Contributing
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.
Code of Conduct
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.
Licensing
Copyright 2022-2022 SAP SE or an SAP affiliate company and cds-dts-generator 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.