@sap/cds-compiler
Version:
CDS (Core Data Services) compiler and backends
1,293 lines (1,252 loc) • 63.4 kB
TypeScript
// Official cds-compiler API.
// All functions and namespace documented here are available when
// @sap/cds-compiler is required.
//
// These types are improved step by step and use a lot any types at the moment.
// Author's note: All "options" interfaces should actually be types. However, due to
// <https://github.com/TypeStrong/typedoc/issues/1519> we can't use
// intersection types at the moment.
export = compiler;
declare namespace compiler {
/**
* Options used by the core compiler and all backends.
*/
export interface Options {
[option: string]: any,
/**
* Compiler and backend messages. Messages can be simple info messages but
* also warnings and errors. It is highly recommended to fix any warnings
* and to not ignore them.
* Errors stop the compilation process.
*/
messages?: object[]
/**
* Dictionary of message-ids and their reclassified severity. This option
* can be used to increase the severity of messages. The compiler may
* ignore decreased severities of error messages as this may lead to issues
* during compilation otherwise.
*/
severities?: { [messageId: string]: MessageSeverity}
/**
* Dictionary of beta flag names. This option allows fine-grained control
* over which beta features should be enabled.
* For a list of beta flag, please refer to `cdsc --help`.
*
* For backwards compatibility, this option may be `true` to indicate that
* all beta features should be enabled.
*/
beta?: { [betaFlag: string]: boolean } | boolean
/**
* If true, internal consistency checks are enabled and recompilation in
* backends is disabled.
*
* @internal This is an internal option and should not be used by end-users.
*/
testMode?: boolean
/**
* If true, CSN definitions are sorted by name. Implicitly enabled when testMode is true.
* `testMode` has higher priority, meaning if `testSortCsn` is `false` and `testMode` is true,
* definitions will still be sorted.
*/
testSortCsn?: boolean
/**
* A JS prototype that will be used for dictionaries created by the compiler.
* Dictionaries are e.g. "definitions" and "elements".
*/
dictionaryPrototype?: any
/**
* CSN Flavor: The compiler supports different CSN flavors. Backends may support
* different flavors. This option is mainly used in `compile()`.
* Flavors are:
* - client : (default) Standard CSN consumable by clients and backends.
* - gensrc : CSN specifically for use as a source, e.g. for combination with
* additional "extend" or "annotate" statements, but not suitable
* for consumption by clients or backends.
* - universal : In development (BETA)
*
* @default 'client'
*/
csnFlavor?: string | 'client' | 'gensrc' | 'universal'
/**
* If set to false, backends will create localized convenience views for those views,
* that only have an association to a localized entity/view. If set to true, views will
* only get a convenience view, if they themselves contain localized elements (i.e. either
* have simple projection on localized elements and CDL-casts to a localized element).
*
* If true, the OData backend will not set `$localized: true` markers for such cases.
*
* Does not work for backends to.hdi(), to.hdbcds() or to.sql() with `sqlDialect: 'hana'`,
* since in all those dialects, associations still exist in generated artifacts.
*
* @default true
*/
fewerLocalizedViews?: boolean
}
/**
* Options relevant for compilation and parsing of CDL and CSN files.
*/
export interface CompileOptions extends Options {
/**
* If the given filename does not have a known file extension,
* use this frontend as the fallback parser.
*/
fallbackParser?: string | 'cdl' | 'csn'
/**
* Where to find `@sap/cds/` packages. This string, if set, is used as
* the prefix for SAP CDS packages / CDS files.
*/
cdsHome?: string
/**
* "Doc comments" (documentation comments) are those comments starting with `/**` in CDL
* or the `doc` property in CSN. This option is an _output_ option, which can have three
* values:
*
* - `true`:
* Doc comments will appear in the compiled CSN. Basic sanity checks are performed:
* In CDL, if a doc comment appears at a not-defined position, where it has no impact,
* an info message is emitted. For CSN input, it is checked that the `doc` property
* is a string or `null`.
*
* - `false`:
* Doc comments will not be parsed for CDL, and will be stripped from input CSN,
* i.e. the compiled CSN (output) does not contain `doc` properties. No checks
* are performed on doc comments.
*
* - `undefined`:
* Doc comments are checked (see value `true`). For CDL, doc comments are not parsed,
* i.e. will not appear in the compiled CSN (output).
* For CSN input, all `doc` properties remain in the CSN.
*
* The CDL equivalent of the CSN value `doc: null`, is an empty doc comment.
*/
docComment?: boolean
/**
* If this option is `true`, doc comments are propagated just like annotations.
* If `false`, they won't be propagated at all.
*
* See option 'docComment'.
*
* Until @sap/cds-compiler v6.0, doc comments were always propagated.
*
* @default `false`
* @since v6.0
*/
propagateDocComments?: boolean
/**
* When set to `true`, and the model contains an entity `sap.common.Languages`
* with an element `code`, all generated texts entities additionally contain
* an element `language` which is an association to `sap.common.Languages`
* using element `locale`.
*
* @since v2.8.0
*/
addTextsLanguageAssoc?: boolean
/**
* An array of directory names that are used for CDS module lookups.
* Lookup directory `node_modules/` is appended if not set explicitly.
*
* All directories in this array follow the same lookup-pattern as `node_modules/`.
*
* See <https://cap.cloud.sap/docs/cds/cdl#model-resolution>
*
* @since v4.2.0
*/
moduleLookupDirectories?: string[]
/**
* An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
* that can be used to abort the compilation.
* Used for any `async` task, i.e. at the moment for reading/parsing files.
*
* Note that this flag has no effect on _synchronous_ compilation functions.
*
* @since v6.1
*/
abortSignal?: AbortSignal
/**
* Option for {@link compileSources}. If set, all objects inside the
* provided sources dictionary are interpreted as XSN structures instead
* of CSN, i.e. a compiler-internal representation.
*
* @since v2.12.1
*/
$xsnObjects?: boolean
/**
* If `true`, the CSN will have an enumerable property `$locations`.
* with values for `line` and `col`, i.e. there is only a start position,
* but no end position.
*
* If `false`, the property will be non-enumerable, i.e. it won't be
* serialized when using `JSON.stringify()`.
*
* With value `"withEndPosition"`, the property will be enumerable and
* will contain values for the end-position. Other string values
* are not allowed. This value was introduced in v5.3.0.
*
* $location is not set on all artifacts, and it only indicates the position
* of the _name_ of the artifact.
*/
withLocations?: boolean|string
/**
* Internal option for LSP only!
* If set, each AST gets a `tokenStream` property containing all lexed tokens.
*
* @private
*/
attachTokens?: boolean
/**
* Internal option for LSP only!
* If set, enables some extra checks/work for the CDS LSP.
* May be implicitly set by `$lsp.<api>` functions.
*
* @private
* @since v4.9
*/
lspMode?: boolean
}
/**
* Options used by OData backends. Includes options for the OData
* transformer as well as for rendering EDM and EDMX.
*/
export interface ODataOptions extends Options {
/**
* OData version for output files. Either 'v4' or 'v2'.
*
* @default 'v4'
*/
odataVersion?: string | 'v4' | 'v2'
/**
* Whether to generate OData as flat or as structured.
* Structured is only supported for OData v4.
*
* @default 'flat'
*/
odataFormat?: string | 'flat' | 'structured'
/**
* Naming mode used by the corresponding SQL.
*
* @default 'plain'
*/
sqlMapping?: string | 'plain' | 'quoted' | 'hdbcds'
/**
* If `true`, `cds.Compositions` are rendered as `edm:NavigationProperty` with the additional
* attribute `ContainsTarget="true"` and all contained entities (composition targets) have no
* `edm.EntitySet`.
*
* @note Only available for OData v4 EDM(X) rendering.
* @default false
*/
odataContainment?: boolean
/**
* If `true`, render generated foreign keys for managed associations.
* By default foreign keys are never visible in structured OData APIs.
*
* @note Only available for structured OData v4 EDM(X) rendering.
* @default false
*/
odataForeignKeys?: boolean
/**
* If `true`, association targets outside of the current service are added as
* `edm.EntityType` that only exposes their primary keys and have no `edm.EntitySet`.
* If the original association target is a service member, a corresponding `edm.Schema`
* representing the namespace of that service is added to `edm.Services`. All association
* targets that are no service members are collected in an `edm.Schema` with namespace `root`.
*
* @note Only valid for structured OData v4 EDM(X) rendering.
* @default false
* @since v2.1.0
*/
odataProxies?: boolean
/**
* This option is an extension to `odataProxies`.
* If `true`, an `edm:Reference` instead of a proxy `edm.EntityType` is rendered for each
* association target that is a service member outside the current service instead of proxies.
*
* @note Only valid for structured OData v4 EDM(X) rendering.
* @default false
* @since v2.1.0
*/
odataXServiceRefs?: boolean
/**
* The OData specification requires that all primary keys of the principal must be used as
* referential constraints. If an association is modelled with only a partial key, no
* referential constraints are added. If `true`, partial constraints are rendered for
* backwards compatibility and mocking scenarios. A spec violation warning is raised for
* each incomplete constraint.
*
* @note Only valid for OData v2 CSN transformation.
* @default false
* @since v2.2.6
*/
odataV2PartialConstr?: boolean
/**
* Service name for which EDMX or EDM shall be rendered.
*
* @note Only available for `to.edmx()` and `to.edm()`. For `to.edmx.all()`
* and `to.edm.all()`, use `serviceNames` instead.
*
* @see serviceNames
*/
service?: string
/**
* Array of service names for which EDMX or EDM shall be rendered.
* If unspecified, all services are rendered.
*
* @note Only available for `to.edmx.all()` and `to.edm.all()`. For `to.edmx()`
* and `to.edm()`, use `service` instead.
*
* @see service
*/
serviceNames?: string[]
/**
* If set, certain OData errors that are not relevant for OpenAPI generation
* are downgraded to warnings when generating EDM JSON.
*
* @default true
* @since v4.8.0
* @private
*/
edm4OpenAPI?: boolean
}
/**
* Options used by the `for.effective()` CSN transformation.
*
* @internal
* @see _for.effective()
*/
export interface EffectiveCsnOptions extends SqlOptions {
/**
* If true, resolve simple type references to their simple base type.
*
* @default true
*/
resolveSimpleTypes?: boolean
/**
* If true, transform projections into ordinary views with SELECT.
*
* @default true
*/
resolveProjections?: boolean
/**
* If true, remap OData annotations to ABAP annotations.
*
* @default false
*/
remapOdataAnnotations?: boolean
/**
* If true, keep '.localized' property in the CSN.
*
* @default false
*/
keepLocalized?: boolean
}
/**
* Options used by SQL `to.sql()` backend.
*
* @see to.sql()
*/
export interface SqlOptions extends Options {
/**
* The SQL naming mode decides how names are represented.
* Among others, this includes whether identifiers are quoted or not (note
* that "smart quoting" is handled by `sqlDialect`).
*
* - `plain`:
* In this naming mode, dots are replaced by underscores.
* Names are neither upper-cased nor quoted, unless "smart-quoting" is used.
* This mode can be used with all SQL dialects.
* - `quoted`:
* In this mode, all identifiers are quoted. Dots are not replaced in table
* and view names but are still replaced by underscores in element names.
* This mode can only be used with SQL dialect `hana`.
* - `hdbcds`:
* This mode uses names that are compatible to SAP HANA CDS.
* In this mode, all identifiers are quoted. Dots are neither replaced in table
* nor element names. Namespace identifiers are separated from the remaining
* identifier by `::`, i.e. the dot is replaced. For example `Ns.Books`
* becomes `"Ns::Books"`.
* This mode can only be used with SQL dialect `hana`.
*
* @default 'plain'
*/
sqlMapping?: string | 'plain' | 'quoted' | 'hdbcds'
/**
* Use this option to specify what dialect of SQL you want.
*
* Different databases may support different feature sets of SQL.
* For example, timestamps are handled differently. Furthermore, "smart-quoting"
* is enabled for all flavors except `plain`. This is useful if identifiers
* collide with reserved keywords.
*
* - `plain`:
* Use this option for best compatibility with standard SQL.
* Note that "smart-quoting" is not available for this mode.
* Requires `sqlMapping: 'plain'`.
* - `sqlite`:
* This SQL dialect ensures compatibility with SQLite, which may not support
* all SQL features used in your CDS files. For example, `$at.from`/`$at.to` are
* handled differently to ensure correctness for SQLite. "smart-quoting"
* quotes identifiers that are reserved keywords, but does not upper-case them.
* Requires `sqlMapping: 'plain'`.
* - `hana`:
* Use this SQL dialect for best compatibility with SAP HANA.
* "smart-quoting" upper-cases and quotes identifiers.
* - `postgres:
* This SQL dialect ensures compatibility with PostgreSQL.
* Does not support `hana.*` types. Requires `sqlMapping: 'plain'`.
* "smart-quoting" quotes identifiers that are reserved keywords, but does not upper-case them.
* Since v3.3.0
* - `h2`
* This SQL dialect ensures compatibility with H2 v2.
* Does not support `hana.*` types. Requires `sqlMapping: 'plain'`.
* "smart-quoting" quotes identifiers that are reserved keywords and upper-cases them.
* Since v3.4.0
*
* @default 'plain'
*/
sqlDialect?: string | 'plain' | 'sqlite' | 'hana' | 'postgres' | 'h2'
/**
* Object containing magic variables. These magic variables are
* used as placeholder values.
*
* @since 2.11.0
*/
variableReplacements?: {
[option: string]: string | object,
/**
* Commonly used placeholders for user's name and locale.
*/
$user?: {
[option: string]: string | object,
id?: string
locale?: string
},
/**
* Commonly used placeholders for session variables.
*/
$session?: Record<string, string | object>
}
/**
* If turned on, renders:
*
* - `$user.‹id|locale›` as `session_context( '$user.‹id|locale›' )`
* instead of requiring them to be set in `sqlOptions.variableReplacements`, and
* - `$at.‹from|to›` and `$valid.‹from|to›` as `session_context( '$valid.‹from|to›' )`
* instead of using `strftime(…)`.
*
* `sqlOptions.variableReplacements` takes precedence for `$user`. If `$user.id` is set,
* the compiler will not render a `session_context(…)` function, even if this option is set.
*
* Only works with sqlDialect 'sqlite'! Otherwise, it has no effect.
*
* @since 3.9.0
* @default true (since v5)
*/
betterSqliteSessionVariables?: boolean
/**
* If set, operator `!=` will be treated as a boolean-logic operator,
* instead of a three-valued operator, by rendering it as `IS DISTINCT FROM`
* on databases that support it, or an equivalent expression.
*
* Note, that if disabled:
* - `!=`, is not translated and is hence treated as `<>`, meaning it uses
* three-valued logic, on databases that support it.
* - `==` is still treated as two-valued logic operator.
*
* This option is the default since cds-compiler v6.
*
* @since 5.9.0
* @default true (since v6.0)
*/
booleanEquality?: boolean
/**
* If set to true, a specified set of functions - inspired by OData and SAP HANA -
* are translated to database-specific variants.
*
* See <https://cap.cloud.sap/docs/guides/databases>
*
* @since 5.9.2
* @default true (since v6.0)
*/
standardDatabaseFunctions?: boolean
/**
* If set to true, variable `$now` will be rendered as 'CURRENT_TIMESTAMP' in
* SQL, instead of `SESSION_CONTEXT('$now')` (or an equivalent clause in other SQL dialects).
*
* In cds-compiler <6, `$now` was always rendered as `CURRENT_TIMESTAMP`.
* Since v6, it is a session variable, except for DEFAULT clauses.
*
* @since 6.0
* @default false
*/
dollarNowAsTimestamp?: boolean
}
/**
* Options used by to.hdbcds()
*/
export interface HdbcdsOptions extends Options {
/**
* The SQL naming mode decides how names are represented.
* Among others, this includes whether identifiers are quoted or not.
*
* - `plain`:
* In this naming mode, dots are replaced by underscores.
* Identifiers are always uppercased. If "smart-quoting" is used, they are also quoted
if they are also HDBCDS keywords.
* - `quoted`:
* In this mode, all identifiers are quoted. Dots are not replaced in table
* and view names but are still replaced by underscores in element names.
* Identifier casing is kept as specified in the source.
* - `hdbcds`:
* This mode uses names that are compatible to SAP HANA CDS.
* In this mode, all identifiers are quoted. Dots are neither replaced in table
* nor element names: Structured elements persist, contexts are nested.
* Managed associations/compositions are left as-is. No association-to-join-translation
* is done.
*
* @default 'plain'
*/
sqlMapping?: string | 'plain' | 'quoted' | 'hdbcds'
/**
* For to.hdbcds(), the SQL dialect is always set to 'hana'.
*/
sqlDialect?: 'hana'
}
/**
* Options used by to.hdi() and to.hdi.migration()
*/
export interface HdiOptions extends Options {
/**
* The SQL naming mode decides how names are represented.
* Among others, this includes whether identifiers are quoted or not.
*
* - `plain`:
* In this naming mode, dots are replaced by underscores.
* Names are neither upper-cased nor quoted, unless "smart-quoting" is used.
* - `quoted`:
* In this mode, all identifiers are quoted. Dots are not replaced in table
* and view names but are still replaced by underscores in element names.
* - `hdbcds`:
* This mode uses names that are compatible to SAP HANA CDS.
* In this mode, all identifiers are quoted. Dots are neither replaced in table
* nor element names. Namespace identifiers are separated from the remaining
* identifier by `::`, i.e. the dot is replaced. For example `Ns.Books`
* becomes `"Ns::Books"`.
*
* @default 'plain'
*/
sqlMapping?: string | 'plain' | 'quoted' | 'hdbcds'
/**
* For to.hdi(), the SQL dialect is always set to 'hana'.
*/
sqlDialect?: 'hana'
/**
* Only for to.hdi.migration().
* SQL change mode to use (for changed columns).
*
* @default 'alter'
*/
sqlChangeMode?: string | 'alter' | 'drop'
/**
* Only for `to.hdi.migration`. If `true`, `to.hdi.migration` allows that the two
* passed CSNs are of different CSN versions. Use at own risk.
*
* @default false
*/
allowCsnDowngrade?: boolean
/**
* If set to true, variable `$now` will be rendered as 'CURRENT_TIMESTAMP'
* instead of `SESSION_CONTEXT('$now')`.
*
* In cds-compiler <6, `$now` was always rendered as `CURRENT_TIMESTAMP`.
* Since v6, it is a session variable, except for DEFAULT clauses.
*
* @since 6.0
* @default false
*/
dollarNowAsTimestamp?: boolean
}
/**
* Options used by `to.cdl()` backend.
*
* @note `to.cdl()` currently has no specific options.
* @see to.cdl()
*/
export interface CdlOptions extends Options {
/**
* If `true`, to.cdl() nests rendered definitions, e.g. all service/context entities
* are nested inside a service/context definition.
* This shortens definition names, as instead of `entity a.b.c.d.E {…}`,
* a `service a.b.c.d {…}` with inner `entity E {…}` is rendered.
* May introduce additional USING statements for paths that can't be reached
* without one inside the current scope, e.g. when paths are shadowed in inner scopes.
*
* __Example__ (also using `renderCdlCommonNamespace: true`):
*
* ```cds
* namespace S;
* using { S as S_ };
* entity Base {
* key id : String;
* };
* service S {
* entity Base as projection on S_.Base as Base;
* };
* ```
*
* If `false`, there is no nesting of definitions inside services or contexts.
* All definitions are defined using their fully qualified path.
*
* __Example__:
*
* ```cds
* entity S.Base {
* key id : String;
* };
* service S.S {};
* entity S.S.Base as projection on S.Base as Base;
* ```
*
* @default true (since v6)
*/
renderCdlDefinitionNesting?: boolean
/**
* If `true`, `to.cdl()` tries to extract a common namespace that is then rendered
* as a `namespace` statement.
*
* Only usable in combination with `renderCdlDefinitionNesting: true`.
*
* @default true (since v6)
*/
renderCdlCommonNamespace?: boolean
}
/**
* The compiler's package version.
* For more details on versioning and SemVer, see `doc/Versioning.md`
*/
export function version(): string;
/**
* Main function: Compile the sources from the files given by the array of
* `filenames`. As usual with the `fs` library, relative file names are
* relative to the working directory `process.cwd()`. With argument `dir`, the
* file names are relative to `process.cwd()+dir` (or just `dir` if it is absolute).
*
* This function returns a Promise and can be used with `await`. For an example
* see `examples/api-usage/`.
* See function {@link compileSync} or {@link compileSources} for alternative compile
* functions.
*
* The promise is fulfilled if all files could be read and processed without
* errors. The fulfillment value is a CSN model.
*
* If there are errors, the promise is rejected. If there was an invocation
* error (repeated filenames or if the file could not be read), the rejection
* value is an {@link InvocationError}. Otherwise, the rejection value is a
* {@link CompilationError} containing a vector of individual errors.
*
* @param filenames Array of files that should be compiled.
* @param dir Working directory. Relative paths in `filenames` will be resolved relatively to this directory.
* @param options Compiler options. If you do not set `messages`, they will be printed to console.
* @param fileCache
*/
export function compile(filenames: string[], dir?: string, options?: CompileOptions, fileCache?: FileCache): Promise<CSN>;
/**
* Synchronous version of {@link compile}.
* Usage is discouraged. Use the asynchronous version if possible.
*
* @see compile
*/
export function compileSync(filenames: string[], dir?: string, options?: CompileOptions, fileCache?: FileCache): CSN;
/**
* Synchronously compiles the given sources.
*
* Argument `sourcesDict` is a dictionary mapping filenames to either source texts (string)
* or JavaScript objects, which are usually CSNs, or XSNs (compiler internal AST-like augmented CSNs).
* The latter requires option `$xsnObjects` to be set to `true`.
* It could also be a simple string, which is then considered to be the source
* text of a file named `<stdin>.cds`.
*
* This function uses the direct value of USINGs (in CSN `"requires"`) for its dependency graph,
* i.e. this function does not resolve USINGs. If a USING matches a key in sourcesDict,
* we assume that it depends on that file (/sourcesDict entry).
*
* See function {@link compile} for the meaning of the argument `options`. If there
* are parse or other compilation errors, throws an exception {@link CompilationError}
* containing a list of individual errors.
*/
export function compileSources(sourcesDict: Record<string, string|object> | string, options?: CompileOptions): CSN;
/**
* In version 2 of cds-compiler, this is an identity function and
* is only kept for backwards compatibility.
*
* @deprecated
* @returns The input parameter "csn".
*/
export function compactModel(csn: CSN): CSN;
/**
* Exception thrown by the compiler if errors are encountered.
*
* Note that compiler functions (e.g. renderers) may not always throw if errors are encountered.
* You always need to check the option's `messages` array for a {@link CompileMessage} of severity 'Error'.
*/
export class CompilationError extends Error {
constructor(messages: CompileMessage[], model?: any, text?: string, ...args: any[]);
/**
* String to identify this class. Can be used instead of relying on `instanceof`.
* Always `ERR_CDS_COMPILATION_FAILURE`.
* @since v4.0.0
*/
code: string;
messages: CompileMessage[];
toString(): string;
/**
* If `options.attachValidNames` is set, this non-enumerable property holds the CSN model.
* @internal
*/
model?: CSN;
}
/**
* Exception thrown by the compiler if {@link compile} and its variants are invoked incorrectly.
* For example, this error is thrown if the same file is passed to {@link compile} twice.
*/
export class InvocationError extends Error {
constructor(errs: any, ...args: any[]);
errors: any[]
}
/**
* Sort the given messages according to their location. Messages are sorted
* in ascending order according to their:
*
* - file name
* - start line
* - start column
* - end line
* - end column
* - semantic location (“home”)
* - message text
*
* If both messages do not have a location, they are sorted by their semantic
* location and then by their message text. If only one message has a file
* location, that message is sorted prior to those that don't have one.
*
* _Note_: Sorting is done in-place.
*
* Example of sorted messages:
* ```
* A.cds:1:11: Info id-3: First message text (in entity:“E”/element:“c”)
* A.cds:8:11: Error id-5: Another message text (in entity:“C”/element:“g”)
* B.cds:3:10: Debug id-7: First message text (in entity:“B”/element:“e”)
* B.cds:3:12: Warning id-4: Message text (in entity:“B”/element:“d”)
* B.cds:3:12: Error id-4: Message text (in entity:“B”/element:“e”)
* ```
*
* If you also want to sort according to message's severity,
* see {@link sortMessagesSeverityAware}.
*
* @returns The same messages array as the input parameter.
*/
export function sortMessages(messages: CompileMessage[]): CompileMessage[];
/**
* Sort the given messages in severity aware order. Messages are sorted first
* by severity where 'Error' comes first, then 'Warning' and so forth.
* Messages of the same severity are sorted the same as by {@link sortMessages}.
*
* _Note_: Sorting is done in-place.
*
* @returns The same messages array as the input parameter.
*/
export function sortMessagesSeverityAware(messages: CompileMessage[]): CompileMessage[];
/**
* Removes duplicate messages from the given messages array without destroying
* references to the array, i.e. removes them in-place.
*
* _Note_: Does NOT keep the original order!
*
* Two messages are the same if they have the same message hash (see below).
* If one of the two is more precise, then it replaces the other.
* A message is more precise if it is contained in the other or if
* the first does not have an `endLine`/`endCol`.
*
* A “message hash” is the string representation of the message. If the
* message does not have a semantic location (“home”), the message hash
* is the result of {@link messageString}. If the message has a semantic
* location, the file location is stripped before being passed to
* {@link messageString}.
*/
export function deduplicateMessages(messages: CompileMessage[]): void;
/**
* Returns a message string with file- and semantic location if present in compact
* form (i.e. one line).
*
* Example:
* ```
* <source>.cds:3:11: Error message-id: Can't find type `nu` in this scope (in entity:“E”/element:“e”)
* ```
*
* @param msg Compiler message which shall be stringified.
* @param normalizeFilename If true, the file path will be normalized to use `/` as the path separator.
* @param noMessageId If true, the message ID will _not_ be part of the string.
* @param noHome If true, the semantic location will _not_ be part of the string.
*
* @deprecated Use messageString(msg, config) instead.
*/
export function messageString(msg: CompileMessage, normalizeFilename?: boolean, noMessageId?: boolean, noHome?: boolean): string;
/**
* Returns a message string with file- and semantic location if present in compact
* form (i.e. one line).
*
* Example:
* ```
* <source>.cds:3:11: Error message-id: Can't find type `nu` in this scope (in entity:“E”/element:“e”)
* ```
*
* Example Usage:
* ```js
* const config = { normalizeFilename: false, noMessageId: true };
* console.log(messages.map(msg => compiler.messageString(msg, config)));
* ```
*
* @param config.normalizeFilename
* If true, the file path will be normalized to use `/` as the path separator (instead of `\` on Windows).
*
* @param config.noMessageId
* If true, will _not_ show the message ID (+ explanation hint) in the output.
*
* @param config.noHome
* If true, will _not_ show message's semantic location.
*
* @param config.moduleForMarker
* If set, downgradable error messages will get a '‹↓›' marker, depending on whether
* the message can be downgraded for the given module. A `‹↑›` is used if the message
* will be an error in the next major cds-compiler release.
* Was called `module` in v4.8.0 and earlier.
*/
export function messageString(msg: CompileMessage, config?: {
normalizeFilename?: boolean
noMessageId?: boolean
noHome?: boolean
module?: string
}): string;
/**
* Returns a message string with file- and semantic location if present in multiline form
* with a source code snippet below that has highlights for the message's location.
* The message (+ message id) are colored according to their severity.
*
* IMPORTANT: Argument `config` should be re-used by subsequent calls to this function,
* because it caches argument `config.sourceLineMap`.
*
* Example Output:
* ```
* Error[message-id]: Can't find type `nu` in this scope
* |
* <source>.cds:3:10, at entity:“E”/element:“e”
* |
* 3 | e : nu;
* | ^^
* ```
*
* Example Usage:
* ```js
* const config = { sourceMap: fileCache, cwd: '' };
* console.log(messages.map(msg => compiler.messageStringMultiline(msg, config)));
* ```
*
* @param config.normalizeFilename
* If true, the file path will be normalized to use `/` as the path separator (instead of `\` on Windows).
*
* @param config.noMessageId
* If true, will _not_ show the message ID (+ explanation hint) in the output.
*
* @param config.hintExplanation
* If true, messages with explanations will get a "…" marker, see {@link hasMessageExplanation}.
*
* @param config.moduleForMarker
* If set, downgradable error messages will get a '‹↓›' marker, depending on whether
* the message can be downgraded for the given module. A `‹↑›` is used if the message
* will be an error in the next major cds-compiler release.
* Was called `module` in v4.8.0 and earlier.
*
* @param config.sourceMap
* A dictionary of filename<->source-code entries. You can pass the fileCache that is used
* by the compiler.
*
* @param config.sourceLineMap
* A dictionary of filename<->source-newline-indices entries. Is used to extract source code
* snippets for message locations. If not set, will be set and filled by this function on-demand.
* An entry is an array of character/byte offsets to new-lines, for example sourceLineMap[1] is the
* end-newline for the second line.
*
* @param config.cwd
* The current working directory (cwd) that was passed to the compiler.
* This value is only used if a source map is provided and relative paths needs to be
* resolved to absolute ones.
*
* @param config.color
* If true/'always', ANSI escape codes will be used for coloring the severity. If false/'never',
* no coloring will be used. If 'auto', we will decide based on certain factors such
* as whether the shell is a TTY and whether the environment variable `NO_COLOR` is
* unset.
*/
export function messageStringMultiline(msg: CompileMessage, config?: {
normalizeFilename?: boolean
noMessageId?: boolean
hintExplanation?: boolean
moduleForMarker?: string
sourceMap?: Record<string, string>
sourceLineMap?: Record<string, number[]>
cwd?: string
color?: boolean | 'auto' | 'always' | 'never'
}): string;
/**
* Returns a context (code) string for the given message that is human readable.
*
* The message context can be used to indicate to users where an error occurred.
* The line length is limited to 100 characters. If the message spans more than three
* lines, only the first three lines are printed and an ellipsis will be appended in the next line.
* If only one line is to be shown, the affected columns will be highlighted by a caret (`^`).
* All lines are prepended by a pipe (`|`) and show the corresponding line number.
*
* Example Output:
* ```
* |
* 13 | num * nu
* | ^^
* ```
*
* @param sourceLines The source code split up into lines, e.g. by `str.split(/\r\n?|\n/);`.
* @param msg Message whose location is used to print the message context.
* @param config Configuration for the message context.
* @param config.color If true, ANSI escape codes will be used for coloring the severity. If false, no
* coloring will be used. If 'auto', we will decide based on certain factors such
* as whether the shell is a TTY and whether the environment variable `NO_COLOR` is
* unset.
*
* @deprecated Use {@link messageStringMultiline} with `config.sourceMap` and `config.sourceLineMap` instead!
*/
export function messageContext(sourceLines: string[], msg: CompileMessage, config?: {
color?: boolean | 'auto'
}): string;
/**
* Get an explanatory text for a complicated compiler message with ID
* messageId. This function does a file lookup in `share/messages`.
* If the message explanation does not exist, an exception is thrown.
*
* @throws May throw an ENOENT error if the message explanation cannot be found.
* @see hasMessageExplanation
*/
export function explainMessage(messageId: string): string;
/**
* Returns `true` if the given messageId has an explanatory text.
* Contrary to {@link explainMessage}, this function does not do
* any file lookup.
*/
export function hasMessageExplanation(messageId: string): boolean;
/**
* Returns true if at least one of the given messages is of severity "Error".
*/
export function hasErrors(messages: CompileMessage[]): boolean;
export namespace parse {
/**
* Parse the given CDL in parseCdl mode and return its corresponding CSN representation.
*
* @param cdl CDL source as string.
* @param filename Filename to be used in compiler messages.
* @param options Compiler options. Note that if `options.messages` is not set, messages will be printed to stderr.
*/
function cdl(cdl: string, filename: string, options?: Options): CSN;
/**
* Parse the given CQL and return its corresponding CQN representation.
*
* @param cdl CDL source as string.
* @param filename Filename to be used in compiler messages, default is '<query>.cds'
* @param options Compiler options. Note that if `options.messages` is not set, messages will be printed to stderr.
* @returns Returns the CSN representation of the expression, i.e. CDS Query Notation.
*/
function cql(cdl: string, filename?: string, options?: Options): CQN;
/**
* Parse the given CDL expression and return its corresponding CXN representation.
*
* @param cdl CDL source as string.
* @param filename Filename to be used in compiler messages, default is '<expr>.cds'
* @param options Compiler options. Note that if `options.messages` is not set, messages will be printed to stderr.
* @returns Returns the CSN representation of the expression, i.e. CDS Expression Notation.
*/
function expr(cdl: string, filename?: string, options?: Options): CXN;
}
/**
* @note Actual name is "for" which can't be used directly in the documentation
* as it is a reserved name in TypeScript.
*
* @see for
*/
export namespace _for {
/**
* Transform the given (inferred/client) CSN into one that is used for OData.
* Changes include flattening, type resolution and more, according to
* the provided options.
*/
function odata(csn: CSN, options?: ODataOptions): CSN;
/**
* Transform the given CSN into one that has these properties:
* - types are resolved
* - elements are flattened
* - …
*
* THIS IS HIGHLY EXPERIMENTAL
*
* Beta flag `effectiveCsn` is required.
*
* @internal
*/
function effective(csn: CSN, options?: EffectiveCsnOptions): CSN;
/**
* Transform the given CSN into one that has the properties required for SEAL
*
* @internal
*/
function seal(csn: CSN, options?: EffectiveCsnOptions): CSN;
/**
* Transform the given (inferred/client) CSN into one that is used by the
* CAP Java runtime. The CSN is structured.
* Changes include draft handling and the tenant discriminator if requested.
*
* @internal
*/
function java(csn: CSN, options?: ODataOptions): CSN;
}
export { _for as for };
export namespace to {
/**
* Renders the given CSN into a CDL source representation.
*
* The CDL string representation may change between minor @sap/cds-compiler
* versions, but when compiled, will return the same CSN again.
* Hence, stylistic changes such as additional whitespace is not considered
* a breaking change.
*
* @returns Object containing the rendered model.
*/
function cdl(csn: CSN, options?: CdlOptions): CdlResult;
namespace cdl {
/**
* Immutable list of reserved keywords in CDL.
* These keywords are used for automatic quoting in {@link to.cdl}.
*/
const keywords: string[];
/**
* Immutable list of CDL functions, used for automatic quoting in {@link to.cdl}.
* Only relevant for element references of path length 1.
*/
const functions: string[];
/**
* If the given `name` requires brackets in SQL, return an escaped
* identifier in brackets.
* Otherwise, return the name without brackets.
*
* NOTE: If `name` contains newline characters, the resulting delimited identifier
* will not be parsable by the compiler!
*
* Example:
* ```js
* to.cdl.smartId('with ![brackets]')
* // '![with ![brackets]]]'
* to.cdl.smartId('OCCURRENCE', null)
* // 'OCCURRENCE'
* to.cdl.smartId('OCCURRENCE', 'REPLACE_REGEXPR')
* // '![OCCURRENCE]'
* to.cdl.smartId('myId')
* // 'myId'
* ```
*
* @param name
* @param [insideFunction=null]
* Inside special functions such as SAP HANA's `OCCURRENCES_REGEXPR`, there are more
* keywords than in other places. Set this value to a function name, if you want to
* handle those additional keywords as well.
*/
function smartId(name: string, insideFunction?: string|null) : string;
/**
* If the given function `name` requires quoting in CDL, return an escaped
* function identifier in brackets for CDL.
* Otherwise, return the function name without brackets.
*
* NOTE: If `name` contains newline characters, the resulting delimited identifier
* will not be parsable by the compiler!
*
* Example:
* ```js
* to.cdl.smartFunctionId('with ![brackets]')
* // '![with ![brackets]]]'
* to.cdl.smartFunctionId('myFunction')
* // 'myFunction'
* ```
*
* @param name
*/
function smartFunctionId(name: string) : string;
/**
* Escapes the given name according to the CDL language and puts it
* into `![` and `]`, properly escaping all `]` in the identifier.
*
* NOTE: If `name` contains newline characters, the resulting delimited identifier
* will not be parsable by the compiler!
*
* Example:
* ```js
* to.cdl.delimitedId('with ![brackets]')
* // '![with ![brackets]]]'
* to.cdl.delimitedId('myId')
* // '![myId]'
* ```
*
* @param name
*/
function delimitedId(name: string) : string;
}
/**
* Renders the given CSN into SQL statements such as `CREATE TABLE`, `CREATE VIEW`, etc.
*
* @returns Array of SQL statements as strings, tables first, views second and optionally table constraints last.
*/
function sql(csn: CSN, options?: SqlOptions): string[];
namespace sql {
namespace sqlite {
/**
* Immutable list of reserved keywords for SQLite. The list is used by {@link to.sql}.
* Taken from <http://www.sqlite.org/draft/lang_keywords.html>.
*/
const keywords: string[];
}
namespace h2 {
/**
* Immutable list of reserved keywords for H2. The list is used by {@link to.sql}.
* Taken from <http://www.h2database.com/html/advanced.html#keywords>.
*/
const keywords: string[];
}
namespace postgres {
/**
* Immutable list of reserved keywords for PostgreSQL. The list is used by {@link to.sql}.
* Taken from <https://www.postgresql.org/docs/current/sql-keywords-appendix.html>.
*/
const keywords: string[];
}
/**
* If the given `name` requires quoting for SQL dialect `dialect`,
* returns a quoted and escaped identifier for that SQL dialect.
* Otherwise, returns the name without quotes.
*
* Example:
* ```js
* to.sql.smartId('with "quotes"', 'sqlite')
* // '"with ""quotes"""'
* to.sql.smartId('SELECT', 'sqlite')
* // '"SELECT"'
* to.sql.smartId('myId', 'sqlite')
* // 'myId'
* ```
*
* @param name
* @param dialect
*/
function smartId(name: string, dialect: string) : string;
/**
* If the given function `name` requires quoting for SQL dialect `dialect`,
* returns a quoted and escaped function identifier for that SQL dialect.
* Otherwise, returns the function name without quotes.
*
* Example:
* ```js
* to.sql.smartFunctionId('with "quotes"', 'sqlite')
* // '"with ""quotes"""'
* to.sql.smartFunctionId('myFunction', 'sqlite')
* // 'myFunction'
* ```
*
* @param name
* @param dialect
*/
function smartFunctionId(name: string, dialect: string) : string;
/**
* Escapes the given name according to the SQL dialect and puts it
* into quotes.
*
* Example:
* ```js
* to.sql.delimitedId('with "quotes"', 'sqlite')
* // '"with ""quotes"""'
* to.sql.delimitedId('myId', 'sqlite')
* // '"myId"'
* ```
*
* @param name
* @param dialect
*/
function delimitedId(name: string, dialect: string) : string;
/**
* Return all non-lossy changes in artifacts between two given models.
* Note: Only supports changes in artifacts compiled/rendered as db-CSN/SQL.
*
* ATTENTION: This function may change without prior notice!
* It is still considered work-in-progress!
*
* @beta
*
* @param csn A client/inferred CSN model representing the desired "after-image"
* @param options SQL specific options
* @param beforeImage A db-transformed CSN representing the "before-image", or null in case no such image
* is known, i.e. for the very first migration step.
* @returns See {@link SqlMigrationResult} for details.
*/
function migration(csn: CSN, options: SqlOptions, beforeImage: CSN): SqlMigrationResult;
}
/**
* Renders the given CSN into EDM in the JSON format _and_ XML format.
* That is, it is a combination of `to.edm()` and `to.edmx()`.
* Requires `options.service` to be set.
*
* Not to be confused with `for.odata()`, which returns an OData transformed CSN.
*
* @returns An object `'<protocol>': object` where the value is `'<serviceName>': object` entry
* which consists of `{edmx: string, edm?: object}`.
* @since v4.6.0
*/
function odata(csn: CSN, options?: ODataOptions): Record<string, object>;
namespace odata {
/**
* Renders the given CSN into EDM in JSON format _and_ XML format for each service.
* That is, it is a combination of `to.edm.all()` and `to.edmx.all()`.
* If `options.serviceNames` is not set, all services will be rendered.
*
* @returns A map of `'<protocol>': object` where each entry is `'<serviceName>': object` entries where
* each entry consists of `{edmx: string, edm?: object}`.
* @since v4.6.0
*/
function all(csn: CSN, options: ODataOptions): Record<string, object>;
}
/**
* Renders the given CSN into EDM (JSON format). Requires `options.service` to be set.
*
* @returns Rendered EDM as JSON structure.
*/
function edm(csn: CSN, options?: ODataOptions): object;
namespace edm {
/**
* Renders the given CSN into EDM (JSON format) for each service.
* If `options.serviceNames` is not set, all services will be rendered.
*
* @returns A map of `{ '<serviceName>': object }` entries.
*/
function all(csn: CSN, options: ODataOptions): Record<string, object>;
}
/**
* Renders the given CSN into EDMX. Requires `options.service` to be set.
*
* @returns Rendered EDMX as string.
*/
function edmx(csn: CSN, options: ODataOptions): string;
namespace edmx {
/**
* Renders the given CSN into EDMX for each service.
* If `options.serviceNames` is not set, all services will be rendered.
*
* @returns A ma