The cds Façade Object
The cds
facade object provides access to all CAP Node.js APIs. Use it like that:
const cds = require('@sap/cds')
let csn = cds.compile(`entity Foo {}`)
const cds = require('@sap/cds')
let csn = cds.compile(`entity Foo {}`)
TIP
Use cds repl
to try out things, for example like this to :
[dev] cds repl
Welcome to cds repl v6.8.0
> cds.compile(`entity Foo { key ID : UUID }`)
{ definitions: {
Foo: { kind: 'entity', elements: { ID: { key: true, type: 'cds.UUID' } } }
}}
[dev] cds repl
Welcome to cds repl v6.8.0
> cds.compile(`entity Foo { key ID : UUID }`)
{ definitions: {
Foo: { kind: 'entity', elements: { ID: { key: true, type: 'cds.UUID' } } }
}}
Refs to Submodules
Many properties of cds are references to submodules, which are lazy-loaded on first access to minimize bootstrapping time and memory consumption. The submodules are documented in separate documents.
- cds. models
- cds. server
- cds. serve()
- cds. services
- cds. middlewares
- cds. protocols
- cds. auth
- cds. connect
- cds. ql
- cds. tx()
- cds. log()
- cds. env
- cds. auth
- cds. i18n
- cds. test
- cds. utils
Builtin Types & Classes
Following properties provide access to the classes and prototypes of linked CSNs.
cds. builtin .types
cds. builtin .classes
Core Classes
cds.Service
cds.EventContext
cds.Event
cds.Request
cds.User
Properties
Following are properties which are not references to submodules.
cds. version
Returns the version of the @sap/cds
package from which the current instance of the cds
facade module was loaded. For example, use that to write version specific code:
if (cds.version[0] < 6) // code for pre cds6 usage
if (cds.version[0] < 6) // code for pre cds6 usage
cds. home
Returns the pathname of the @sap/cds
installation folder from which the current instance of the cds
facade module was loaded.
[dev] cds repl
> cds.home
~/.npm/lib/node_modules/@sap/cds
[dev] cds repl
> cds.home
~/.npm/lib/node_modules/@sap/cds
cds. root
Returns the project root that is used by all CAP runtime file access as the root directory. By default tihs is process.cwd()
, but can be set to a different root folder. It's guaranteed to be an absolute folder name.
// Print current project's package name
let package_json = path.join (cds.root,'package.json')
let { name, description } = require(package_json)
console.log ({ name, description })
// Print current project's package name
let package_json = path.join (cds.root,'package.json')
let { name, description } = require(package_json)
console.log ({ name, description })
cds. cli
Provides access to the parsed effective cds
cli command and arguments. Example: If you would add log respective output in a project-local server.js
, and start your server with cds watch
, you'd see an output like this:
Trace : {
command: 'serve',
argv: [ 'all' ],
options: {
'with-mocks': true,
'in-memory?': true
}
}
Trace : {
command: 'serve',
argv: [ 'all' ],
options: {
'with-mocks': true,
'in-memory?': true
}
}
For example, cds-plugins
can use that to plugin to different parts of the framework for different commands being executed.
cds. env
Provides access to the effective configuration of the current process, transparently from various sources, including the local package.json or .cdsrc.json, service bindings and process environments.
[dev] cds repl
> cds.env.requires.auth
{
kind: 'basic-auth',
strategy: 'mock',
users: {
alice: { tenant: 't1', roles: [ 'cds.Subscriber', 'admin' ] },
bob: { tenant: 't1', roles: [ 'cds.ExtensionDeveloper' ] },
// ...,
'*': true
},
tenants: {
t1: { features: [ 'isbn' ] },
t2: { features: '*' }
}
}
[dev] cds repl
> cds.env.requires.auth
{
kind: 'basic-auth',
strategy: 'mock',
users: {
alice: { tenant: 't1', roles: [ 'cds.Subscriber', 'admin' ] },
bob: { tenant: 't1', roles: [ 'cds.ExtensionDeveloper' ] },
// ...,
'*': true
},
tenants: {
t1: { features: [ 'isbn' ] },
t2: { features: '*' }
}
}
cds. requires
... is a convenience shortcut to cds.env.requires
.
[dev] cds repl
> cds.requires.auth
{
kind: 'basic-auth',
// ... as above
}
[dev] cds repl
> cds.requires.auth
{
kind: 'basic-auth',
// ... as above
}
cds. services
A dictionary and cache of all instances of cds.Service
constructed through cds.serve
, or connected to by cds.connect
so far.
It’s an iterable object, so can be accessed in the following ways:
let { CatalogService, db } = cds.services
let all_services = [ ... cds.services ]
for (let k in cds.services) //... k is a services's name
for (let s of cds.services) //... s is an instance of cds.Service
let { CatalogService, db } = cds.services
let all_services = [ ... cds.services ]
for (let k in cds.services) //... k is a services's name
for (let s of cds.services) //... s is an instance of cds.Service
cds. context
Provides access to common event context properties like tenant
, user
, locale
as well as the current root transaction for automatically managed transactions.
Learn more about that in reference docs for cds.tx
.
cds. model
The effective CDS model loaded during bootstrapping, which contains all service and entity definitions, including required services. Many framework operations use that as a default where models are required. It is loaded in built-in server.js
like so:
cds.model = await cds.load('*')
cds.model = await cds.load('*')
Learn more about bootstrapping in cds.server
.
cds. app
The express.js Application object constructed during bootstrapping. Several framework operations use that to add express handlers or middlewares. It is initialised in built-in server.js
like so:
cds.app = require('express')()
cds.app = require('express')()
Learn more about bootstrapping in cds.server
.
cds. db
A shortcut to cds.services.db
, the primary database connected to during bootstrapping. Many framework operations use that to address and interact with the primary database. In particular that applies to the global cds.ql
statement objects. For example:
let books = await SELECT.from(Books) // is a shortcut for:
let books = await cds.db.run ( SELECT.from(Books) )
let books = await SELECT.from(Books) // is a shortcut for:
let books = await cds.db.run ( SELECT.from(Books) )
It is initialized in built-in server.js
like so:
cds.db = await cds.connect.to('db')
cds.db = await cds.connect.to('db')
Learn more about bootstrapping in cds.server
.
Methods
cds. error()
function cds.error (
message : string | object,
details? : object
caller? : function
)
function cds.error (
message : string | object,
details? : object
caller? : function
)
This is a helper to construct new errors in various ways:
let e = new cds.error ('message')
let e = new cds.error ('message', { code, ... })
let e = new cds.error ({ message, code, ... })
let e = new cds.error ('message')
let e = new cds.error ('message', { code, ... })
let e = new cds.error ({ message, code, ... })
If called without new
the error is thrown immediately allowing code like that:
let e = foo || cds.error (`Expected 'foo' to be truthy, but got: ${foo}`)
let e = foo || cds.error (`Expected 'foo' to be truthy, but got: ${foo}`)
You can also use cds.error
with tagged template strings:
let e = foo || cds.error `Expected 'foo' to be truthy, but got: ${foo}`
let e = foo || cds.error `Expected 'foo' to be truthy, but got: ${foo}`
In contrast to basic template strings, passed in objects are added using Node's
util.format()
instead oftoString()
.
Method cds.error.expected
allows to conveniently construct error messages as above:
let e = foo || cds.error.expected `${{foo}} to be truthy`
let e = foo || cds.error.expected `${{foo}} to be truthy`
Optional argument caller
can be a calling function to truncate the error stack. Default is cds.error
itself, so it will never show up in the stacks.
cds. exit()
Provides a graceful shutdown for running servers, by first emitting cds.emit('shutdown')
with handlers allowed to be async
functions. If not running in a server, it calls process.exit()
cds.on('shutdown', async()=> fs.promises.rm('some-file.json'))
cds.on('shutdown', ()=> console.log('shutdown'))
cds.exit() //> will rune above handlers before stopping the server
cds.on('shutdown', async()=> fs.promises.rm('some-file.json'))
cds.on('shutdown', ()=> console.log('shutdown'))
cds.exit() //> will rune above handlers before stopping the server