Socket
Socket
Sign inDemoInstall

@sap/cds-compiler

Package Overview
Dependencies
Maintainers
1
Versions
106
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sap/cds-compiler - npm Package Compare versions

Comparing version 1.42.2 to 1.43.0

lib/utils/.eslintrc.json

2

bin/cdsc.js

@@ -128,3 +128,3 @@ #!/usr/bin/env node

'dontRenderVirtualElements': true,
'ignoreManagedAssocPublishingInUnion': true
'ignoreAssocPublishingInUnion': true
}

@@ -131,0 +131,0 @@ }

@@ -9,2 +9,25 @@ # ChangeLog for cdx compiler and backends

## Version 1.43.0 - 2020-10-02
### Added
- The magic variable `$session` is now supported. All element accesses are unchecked.
- Reference paths as annotation values can now contain identifiers starting with `@`.
### Changed
- OData:
+ Raise message level for illegal OData identifiers from warning to error.
+ Update vocabularies 'Aggregation' and 'Common'.
### Fixed
- to.hdi/hdbcds/sql: Correctly process the elements of subqueries in localized view variants
### Removed
### Fixed
- OData: put default value validation under `beta:odataDefaultValues`
## Version 1.42.2 - 2020-09-29

@@ -11,0 +34,0 @@

@@ -10,9 +10,20 @@ # ChangeLog of Beta Features for cdx compiler and backends

## Version 1.42.0
## Version 1.43.0
### Added `ignoreManagedAssocPublishingInUnion`
### Changed `subElemRedirections`
For `to.hdbcds`, with beta flag `ignoreManagedAssocPublishingInUnion` in conjunction with dialect
`hanaJoins`, managed associations in UNIONs are replaced by their foreign keys and silently ignored
When the beta option `subElemRedirections` is set to true,
_all_ array (new!) and structure types are expanded when referenced:
managed associations (and compositions to entities) in that array are
implicitly redirected when necessary.
See [below for details](#version-1300---20200612).
Nested array types (without intermediate structure types) are not supported.
### Added `ignoreAssocPublishingInUnion`
For `to.hdbcds`, with beta flag `ignoreAssocPublishingInUnion` in conjunction with dialect
`hanaJoins`, unmanaged associations in UNIONs are silently ignored and managed associations
are replaced by their foreign keys and silently ignored
## Version 1.36.0 - 2020-08-07

@@ -19,0 +30,0 @@

@@ -955,6 +955,10 @@ 'use strict';

// Return a set of options containing the defaults that would be applied by the backends.
// Note that this only contains simple mergeable default values, not conditional defaults
// that depend in any way on other options (e.g. toSql provides 'src' if neither 'src' nor
// 'csn' is given: this is a conditional default).
/**
* Return a set of options containing the defaults that would be applied by the backends.
* Note that this only contains simple mergeable default values, not conditional defaults
* that depend in any way on other options (e.g. toSql provides 'src' if neither 'src' nor
* 'csn' is given: this is a conditional default).
*
* @returns {CSN.Options}
*/
function getDefaultBackendOptions() {

@@ -961,0 +965,0 @@ return {

'use strict';
// This file contains functions related to XSN/CSN-location objects.
// This file contains functions related to XSN/CSN-location objects as well
// as for semantic locations
const { analyseCsnPath, traverseQuery } = require('../model/csnRefs');
/**

@@ -17,3 +20,3 @@ * Create a location with location properties `filename` and `start` from

start: start.location.start,
end: end && end.location && end.location.end
end: end && end.location && end.location.end,
};

@@ -98,15 +101,234 @@ }

const locations = [].concat( ...dict.map( objLocations ) );
const locations = [].concat( ...dict.map( _objLocations ) );
if (extraLocation)
locations.push( extraLocation );
const min = locations.reduce( (a,b) => a.start.offset < b.start.offset ? a : b );
const max = locations.reduce( (a,b) => (a.end || a.start).offset > (b.end || b.start).offset ? a : b );
const min = locations.reduce( (a, b) => (a.start.offset < b.start.offset ? a : b) );
const max = locations.reduce( (a, b) => ((a.end || a.start).offset > (b.end || b.start).offset ? a : b) );
return { filename: min.filename, start: min.start, end: max.end };
}
function objLocations( obj ) {
function _objLocations( obj ) {
return (obj instanceof Array) ? obj.map( o => o.location ) : [ obj.location ];
}
function constructSemanticLocationFromCsnPath(csnPath, model) {
// Copy because this function shift()s from the path.
csnPath = [ ...csnPath ];
const csnDictionaries = [
'args', 'params', 'enum', 'mixin', 'elements', 'actions', 'definitions',
];
const queryProps = [ 'from', 'where', 'groupBy', 'having', 'orderBy', 'limit', 'offset' ];
let { query } = analyseCsnPath(
csnPath,
model
);
// remove definitions
csnPath.shift();
const artName = csnPath.shift();
let currentThing = model.definitions[artName];
let result = `${ (currentThing && currentThing.kind) ? currentThing.kind : 'artifact' }:${ _quoted(artName) }`;
if (query)
query = queryDepth(currentThing.query, query);
const elements = [];
let inCsnDict = false;
let inElement = false;
let inAction = false;
let inParam = false;
let inKeys = false;
let inRef = false;
let inEnum = false;
let inQuery = false;
let inColumn = false;
let inMixin = false;
let inItems = false;
// for top level actions
if (currentThing.kind === 'action')
inAction = true;
for (const [ index, step ] of csnPath.entries()) {
currentThing = currentThing[step];
if (csnDictionaries.includes(step) && !inCsnDict) {
inCsnDict = true;
switch (step) {
case 'elements':
if (!inElement){
inElement = true;
// do not print intermediate items
inItems = false;
}
break;
case 'actions':
inAction = true;
break;
case 'params':
inParam = true;
break;
case 'enum':
inElement = false;
inEnum = true;
break;
case 'mixin':
inMixin = true;
inQuery = false;
break;
default:
if (inElement) {
// close element
result += element();
inElement = false;
}
}
}
else if ( inQuery ) {
if (step === 'SELECT') {
if (!csnPath[index + 1]) {
result += select();
}
else if (queryProps.includes(csnPath[index + 1]) && !csnPath[index + 2]) {
const clause = csnPath[index + 1];
result += select();
result += `/${ clause }`;
}
}
else if (step === 'columns') {
result += select();
result += '/column';
inColumn = true;
inQuery = false;
}
}
else if ( inMixin ) {
if (step === 'on') {
result += '/on';
break;
}
else {
result += selectAndMixin(step);
}
}
else if (inEnum) {
result += elementAndEnum(step);
}
else if (!inElement && step === 'query') {
inQuery = true;
}
else if (inElement && step === 'keys') {
// close element
result += `${ element() }/key`;
inElement = false;
inKeys = true;
}
else if (inElement && step === 'on') {
// close element
result += `${ element() }/on`;
inElement = false;
break;
}
else if (inElement && step === 'items') {
// this is an element called items
if (csnPath[index - 1] === 'elements' && elements[elements.length - 1] !== 'elements') {
elements.push(step);
}
else {
inElement = false;
inItems = true;
}
}
else if (inElement && step === 'elements') {
// this is an element called elements
if (csnPath[index - 1] === 'elements')
elements.push(step);
}
else if (inItems && step === 'elements') {
inElement = true;
inItems = false;
}
else if ( inKeys || inColumn) {
if (typeof step === 'number') {
if (currentThing.as)
result += `:${ _quoted(currentThing.as) }`;
else
result += inRef ? `:${ _quoted(currentThing) }` : currentThing.ref ? `:${ _quoted(currentThing.ref.join('.')) }` : '';
break;
}
if ( step === 'ref')
inRef = true;
}
else if (inAction && step === 'returns') {
result += `/${ step }`;
break;
}
else if (inCsnDict) {
if (inElement)
elements.push(step);
else if (inParam)
result += param(step);
else if (inAction)
result += func(step);
inCsnDict = false;
}
}
if ( inItems )
result += `${ element() }/items`;
else if ( inElement )
result += element();
return result;
function select() {
let s = '/select';
s += query.isOnlySelect ? '' : `:${ query.depth }`;
return s;
}
function selectAndMixin(name) {
return `${ select() }/mixin:${ _quoted(name) }`;
}
function element() {
return `/element:${ _quoted(elements.join('.')) }`;
}
function param(name) {
return `/param:${ _quoted(name) }`;
}
function func(name) {
return `/function:${ _quoted(name) }`;
}
function elementAndEnum(name) {
return `${ element() }/enum:${ _quoted(name) }`;
}
/**
* Traverse rootQuery until targetQuery is found and count the depth,
* check if targetQuery is only select in entity.
*/
function queryDepth(rootQuery, targetQuery) {
let targetQueryDepth = 1;
let totalQueryDepth = 0;
let isFound = false;
traverseQuery(rootQuery, null, (q, querySelect) => {
if ( querySelect )
totalQueryDepth += 1;
if ( querySelect && !isFound)
targetQueryDepth += 1;
if (q === targetQuery)
isFound = true;
});
return { depth: targetQueryDepth, isOnlySelect: totalQueryDepth === 1 };
}
}
function _quoted( name ) {
return (name) ? `"${ name.replace( /"/g, '""' ) }"` : '<?>'; // sync ";
}
module.exports = {

@@ -119,2 +341,3 @@ combinedLocation,

dictLocation,
constructSemanticLocationFromCsnPath,
};
const { CompileMessage, DebugCompileMessage } = require('../base/messages');
const { analyseCsnPath, traverseQuery } = require('../model/csnRefs');
const { constructSemanticLocationFromCsnPath } = require('./location');

@@ -66,205 +66,7 @@ /**

}
return constructSemanticLocation([...csnPath], model);
return constructSemanticLocationFromCsnPath(csnPath, model);
}
}
function constructSemanticLocation(csnPath, model) {
const csnDictionaries = [
'args', 'params', 'enum', 'mixin', 'elements', 'actions', 'definitions',
];
let { query } = analyseCsnPath(
csnPath,
model
);
// remove definitions
csnPath.shift();
const artName = csnPath.shift();
let currentThing = model.definitions[artName];
let result = ((currentThing && currentThing.kind) ? currentThing.kind : 'artifact') + ':' + quoted(artName);
if(query) {
query = queryDepth(currentThing.query, query);
}
let elements = [];
let inCsnDict, inElement, inAction, inParam, inKeys, inRef, inEnum, inQuery, inColumn, inMixin, inItems = false;
// for top level actions
if(currentThing.kind === 'action')
inAction = true;
for(const [index, step] of csnPath.entries()){
currentThing = currentThing[step];
if(csnDictionaries.includes(step) && !inCsnDict) {
inCsnDict = true;
switch (step) {
case 'elements':
if(!inElement) {
inElement = true;
}
break;
case 'actions':
inAction = true;
break;
case 'params':
inParam = true;
break;
case 'enum':
inElement = false;
inEnum = true;
break
case 'mixin':
inMixin = true;
inQuery = false;
break;
default:
if (inElement) {
// close element
result += element();
inElement = false;
}
}
}
else if( inQuery ){
if(step === 'SELECT') {
if(!csnPath[index + 1]) {
result += select();
} else if (['from', 'where', 'groupBy', 'having', 'orderBy', 'limit', 'offset'].includes(csnPath[index + 1]) && !csnPath[index + 2]) {
let clause = csnPath[index + 1];
result += select();
result += '/' + clause;
}
}
else if(step === 'columns'){
result += select();
result += '/column';
inColumn = true;
inQuery = false;
}
}
else if( inMixin ) {
if(step === 'on') {
result += '/on';
break;
} else {
result += selectAndMixin(step);
}
}
else if(inEnum) {
result += elementAndEnum(step);
}
else if(!inElement && step === 'query'){
inQuery = true;
}
else if(inElement && step === 'keys') {
// close element
result += element() + '/key';
inElement = false;
inKeys = true;
}
else if(inElement && step === 'on') {
// close element
result += element() + '/on';
inElement = false;
break;
}
else if(inElement && step === 'items') {
// this is an element called items
if(csnPath[index - 1] === 'elements' && elements[elements.length - 1] !== 'elements'){
elements.push(step);
}
else {
inElement = false;
inItems = true;
}
}
else if(inElement && step === 'elements') {
// this is an element called elements
if(csnPath[index - 1] === 'elements'){
elements.push(step);
}
}
else if(inItems && step === 'elements') {
inElement = true;
inItems = false;
}
else if( inKeys || inColumn){
if (typeof step === 'number') {
if(currentThing.as) {
result += ':' + quoted(currentThing.as);
}else {
result += inRef ? ':' + quoted(currentThing) : currentThing.ref ? ':' + quoted(currentThing.ref.join('.')) : '';
}
break;
}
if( step === 'ref'){
inRef = true;
}
}
else if(inAction && step === 'returns') {
result += '/' + step;
break;
}
else if(inCsnDict) {
if (inElement)
elements.push(step);
else if(inParam){
result += param(step);
} else if(inAction){
result += func(step);
}
inCsnDict = false;
}
}
if( inItems ) result += element() + '/items';
else if( inElement ) result += element();
return result;
function select() {
let s = '/select';
s += query.isOnlySelect ? '' : ':' + query.depth;
return s;
}
function selectAndMixin(name) {
return `${select()}/mixin:${quoted(name)}`;
}
function element() {
return `/element:${quoted(elements.join('.'))}`;
}
function param(name) {
return `/param:${quoted(name)}`;
}
function func(name) {
return `/function:${quoted(name)}`;
}
function elementAndEnum(name) {
return `${element()}/enum:${quoted(name)}`;
}
/**
* Traverse rootQuery until targetQuery is found and count the depth,
* check if targetQuery is only select in entity.
*/
function queryDepth (rootQuery, targetQuery) {
let targetQueryDepth = 1;
let totalQueryDepth = 0;
let isFound = false;
traverseQuery(rootQuery, null, function countSelect(q, select) {
if( select ) totalQueryDepth += 1;
if( select && !isFound) targetQueryDepth += 1;
if(q === targetQuery) isFound = true;
});
return { depth: targetQueryDepth, isOnlySelect: totalQueryDepth === 1 };
}
}
function quoted( name ) {
return (name) ? '"' + name.replace( /"/g, '""' ) + '"' : '<?>'; // sync ";
}
module.exports = buildMessage;

@@ -149,3 +149,5 @@ 'use strict';

let assocType = isComposition(elem.type) ? 'composition' : 'association';
signal(warning`The ${assocType} "${elem.name.id}" has cardinality "to many" but no ON-condition`, elem.location, undefined, isNoDb ? 'to-many-no-on-noDB' : 'to-many-no-on');
signal(warning`The ${assocType} "${elem.name.id}" has cardinality "to many" but no ON-condition`,
elem.cardinality.location || elem.name.location, undefined,
isNoDb ? 'to-many-no-on-noDB' : 'to-many-no-on');
}

@@ -152,0 +154,0 @@ }

'use strict';
const { isBetaEnabled } = require("../../base/model");
// Only to be used with validator.js - a correct this value needs to be provided!

@@ -10,3 +12,7 @@

if(member.default && this.csn.options.toOdata) {
// TODO: On removal of the beta flag, filter out all illegal OData default values that are legal in the database
// These are all sorts of expressions, functions, $now and turn the message into appropriate warnings
// Or leave them as errors and get through the spec meeting.
if(member.default && this.csn.options.toOdata && isBetaEnabled(this.csn.options, 'odataDefaultValues')) {
// unary minus is xpr: [ "-", { val: ... } ]

@@ -23,3 +29,3 @@ let def = member.default;

if(!(def.val !== undefined || def['#'])) {
this.signal(this.error`Default value must be a simple value`, path);
this.signal(this.error`Default value must be a simple value for OData exposure`, path);
}

@@ -26,0 +32,0 @@ }

@@ -193,3 +193,3 @@ // Consistency checker on model (XSN = augmented CSN)

requires: [ 'kind', 'name' ],
optional: [ 'elements', '$autoElement', '_finalType', '_deps' ],
optional: [ 'elements', '$autoElement', '$uncheckedElements', '_finalType', '_deps' ],
schema: {

@@ -199,2 +199,3 @@ kind: { test: isString, enum: [ 'builtin' ] },

$autoElement: { test: isString },
$uncheckedElements: { test: isBoolean },
// missing location for normal "elements"

@@ -201,0 +202,0 @@ elements: { test: TODO },

@@ -54,2 +54,5 @@ // The builtin artifacts of CDS

/**
* Variables that have special meaning in CDL/CSN.
*/
const magicVariables = { // in SQL-92

@@ -66,2 +69,3 @@ CURRENT_DATE: {},

elements: { id: {}, locale: {} },
// Allow shortcut in CDL: `$user` becomes `$user.id` in CSN.
$autoElement: 'id',

@@ -73,2 +77,7 @@ }, // CDS-specific, not part of SQL

$now: {}, // Dito
$session: {
// In ABAP CDS session variables are accessed in a generic way via
// the pseudo variable $session.
$uncheckedElements: true,
},
};

@@ -221,2 +230,4 @@

art.$autoElement = magic.$autoElement;
if (magic.$uncheckedElements)
art.$uncheckedElements = magic.$uncheckedElements;
// setProp( art, '_finalType', art );

@@ -223,0 +234,0 @@ }

@@ -615,2 +615,6 @@ // Compiler functions and utilities shared across all phases

}
else if (art.$uncheckedElements) {
// do not check any elements of the path, e.g. $session
return art;
}
else {

@@ -617,0 +621,0 @@ const env = (spec.envFn || environment)( art, item.location, user, spec.assoc );

@@ -650,3 +650,3 @@ 'use strict';

if(!edmUtils.isSimpleIdentifier(identifier)){
message(signal.warning, context,
message(signal.error, context,
`OData annotation term "${identifier}" must consist of one or more dot separated simple identifiers (each starting with a letter or underscore, followed by at most 127 letters)`)

@@ -664,3 +664,3 @@ }

if (!edmUtils.isSimpleIdentifier(p[1])) {
message(signal.warning, context,
message(signal.error, context,
`OData annotation qualifier "${p[1]}" must start with a letter or underscore, followed by at most 127 letters, underscores or digits`);

@@ -667,0 +667,0 @@ }

@@ -850,5 +850,7 @@ // @ts-nocheck

}
this[`Default${this.v4 ? 'Value' : ''}`] = ['cds.Boolean', 'cds.Binary', 'cds.LargeBinary', 'cds.Integer64', 'cds.Integer'].includes(csn.type)
if(defVal !== undefined) {
this[`Default${this.v4 ? 'Value' : ''}`] = ['cds.Boolean', 'cds.Binary', 'cds.LargeBinary', 'cds.Integer64', 'cds.Integer'].includes(csn.type)
? defVal
: edmUtils.escapeString(defVal);
}
}

@@ -855,0 +857,0 @@ }

@@ -354,4 +354,6 @@ 'use strict';

let structParent = def.items || def;
// Iterate all struct elements
forEachGeneric(def, 'elements', (element, elementName) => {
forEachGeneric(structParent, 'elements', (element, elementName) => {
initElement(element, elementName, def);

@@ -361,3 +363,3 @@

signal(
signal.warning`OData property name: "${elementName}" must start with a letter or underscore, followed by at most 127 letters, underscores or digits`,
signal.error`OData property name: "${elementName}" must start with a letter or underscore, followed by at most 127 letters, underscores or digits`,
['definitions', def.name, 'elements', elementName]

@@ -837,3 +839,3 @@ );

function signalIllegalIdentifier(identifier, path, kind, msg) {
signal(signal.warning`OData ${kind} ${identifier ? `: "${identifier}"` : ''} ${ msg ? msg : 'must start with a letter or underscore, followed by at most 127 letters, underscores or digits' }`, path);
signal(signal.error`OData ${kind} ${identifier ? `: "${identifier}"` : ''} ${ msg ? msg : 'must start with a letter or underscore, followed by at most 127 letters, underscores or digits' }`, path);
}

@@ -840,0 +842,0 @@

@@ -352,3 +352,3 @@ 'use strict';

for(let fk of assocCsn.keys) {
let realFk = assocCsn._parent.elements[fk.$generatedFieldName];
let realFk = assocCsn._parent.items ? assocCsn._parent.items.elements[fk.$generatedFieldName] : assocCsn._parent.elements[fk.$generatedFieldName];
let pk = assocCsn._target.elements[fk.ref[0]];

@@ -355,0 +355,0 @@ if(pk && pk.key && isConstraintCandidate(pk) && isConstraintCandidate(realFk))

@@ -1273,3 +1273,3 @@ // CSN frontend - transform CSN into XSN

const keySpec = { dictionaryOf: translations, prop: langKey };
return dictionaryOf( translations )( val, keySpec, xsn, csn );
return dictionaryOf( translations )( val, keySpec );
}

@@ -1276,0 +1276,0 @@

@@ -322,3 +322,3 @@ // Transform augmented CSN into compact "official" CSN

for (const name of Object.keys( model.definitions ).sort()) {
for (const name of Object.keys( model.definitions || {} ).sort()) {
const art = model.definitions[name];

@@ -325,0 +325,0 @@

@@ -52,3 +52,3 @@ // Generic ANTLR parser class with AST-building functions

setMaxCardinality,
makeAnnotationIdentifier,
pushIdent,
handleComposition,

@@ -339,2 +339,3 @@ hanaFlavorOnly,

if (sign) {
// TODO: warning for space in between
let end = location.end;

@@ -402,18 +403,25 @@ location = this.startLocation( sign );

function makeAnnotationIdentifier( at, identifier ) {
if (!identifier)
return identifier;
const atLoc = { location: this.startLocation( at ) };
if (identifier.id)
identifier.id = '@' + identifier.id;
// `.stop` does not point to *after* the character as opposed to XSN locations.
if (at.stop + 1 !== identifier.location.start.offset) {
this.message("syntax-anno-space", identifier.location, {}, 'Error',
'Expected identifier after \'@\' but found whitespace')
function pushIdent( path, ident, prefix ) {
if (!ident) {
path.broken = true;
}
identifier.location = this.combinedLocation( atLoc, identifier );
return identifier;
else if (!prefix) {
path.push( ident );
}
else {
const { start, end } = this.tokenLocation( prefix );
if (end.line !== ident.location.start.line || // end.offset will disappear
end.column !== ident.location.start.column) {
const wsLocation = {
filename: ident.location.filename,
start: end, // !
end: { ...ident.location.start },
};
this.message( 'syntax-anno-space', wsLocation, {}, 'Error', // TODO: really Error?
'Expected identifier after \'@\' but found whitespace' );
}
ident.location.start = start;
ident.id = prefix.text + ident.id;
path.push( ident );
}
}

@@ -512,2 +520,3 @@

// Then this check can be removed
// @ts-ignore `location` may exist on props even though it's an array.
this.message( null, props.location || location || this.startLocation( this._ctx.start ), {},

@@ -514,0 +523,0 @@ 'Error', 'Remove the parentheses around the expression' );

@@ -13,3 +13,3 @@ 'use strict'

* @callback genericCallback
* @param {CSN.Member} art
* @param {CSN.Artifact} art
* @param {CSN.FQN} name Artifact Name

@@ -147,3 +147,3 @@ * @param {string} prop Dictionary Property

function isManagedAssociationElement(node) {
return node.target !== undefined && node.on === undefined;
return node.target !== undefined && node.on === undefined && node.keys;
}

@@ -409,3 +409,3 @@

* Deeply clone the given CSN model and return it.
* @param {CSN.Model} csn
* @param {object} csn
*/

@@ -444,3 +444,3 @@ function cloneCsn(csn){

* @param {genericCallback|genericCallback[]} callback
* @param {string[]} [path]
* @param {CSN.Path} [path]
* @param {boolean} [ignoreIgnore]

@@ -657,3 +657,3 @@ */

* @param {CSN.Element} elementCsn
* @param {CSN.Options & { isStructFormat: boolean}} options EDM specific options
* @param {CSN.Options & CSN.OdataOptions} options EDM specific options
*/

@@ -751,3 +751,3 @@ function isEdmPropertyRendered(elementCsn, options) {

* @param {object} csn CSN to enrich in-place
* @param {object} customTransformers Map of prop to transform and function to apply
* @param {object} customTransformers Map of prop to transform and function to apply
* @param {Function[]} artifactTransformers Transformations to run on the artifacts, like forEachDefinition

@@ -754,0 +754,0 @@ * @param {Boolean} skipIgnore Wether to skip _ignore elements or not

@@ -25,2 +25,3 @@ 'use strict';

forEachDefinition(csn, (def, definitionName) => {
/** @type {CSN.Path} */
let root = ['definitions', definitionName];

@@ -27,0 +28,0 @@ forEachMemberRecursively(def, (element, elementName, _prop, subpath, parent) => {

@@ -27,3 +27,3 @@ 'use strict';

if (def.kind === 'type') {
forEachMember(def, (element, elementName, propertyName) => {
forEachMember(def, (element, elementName, propertyName, path) => {
if (propertyName === 'elements') {

@@ -67,3 +67,3 @@ exposeStructTypeOf(element, `${defName}.${elementName}`, getServiceOfArtifact(defName, services), `${defName.replace(/\./g, '_')}_${elementName}`, structuredOData, path);

// then expose T and assign it do the member.
forEachMemberRecursively(def, (member, memberName) => {
forEachMemberRecursively(def, (member, memberName, prop, path) => {
// we do apply array of exposure logic on actions/functions

@@ -76,5 +76,5 @@ // and on params and returns of action/function always,

if (structuredOData)
exposeArrayOfTypeOf(member, memberName, serviceName, `${defNameWithoutServiceName(defName, serviceName)}_${memberName}`);
exposeArrayOfTypeOf(member, memberName, serviceName, `${defNameWithoutServiceName(defName, serviceName)}_${memberName}`, path);
else if (options.toOdata.version === 'v4' && !isAction) {
exposeArrayOfTypeOf(member, memberName, serviceName, `${defNameWithoutServiceName(defName, serviceName)}_${memberName}`);
exposeArrayOfTypeOf(member, memberName, serviceName, `${defNameWithoutServiceName(defName, serviceName)}_${memberName}`, path);
}

@@ -231,3 +231,3 @@ }

if (node.items && !node.type) {
exposeStructTypeOf(node, memberName, service, artificialName, true, path);
exposeStructTypeOf(node.items, memberName, service, artificialName, true, path.concat('items'));
}

@@ -244,3 +244,3 @@ // we can have both of the 'type' and 'items' in the cases:

let typeId = `${service}.${node.type}`;
let newType = exposeArrayedType(csnUtils.getFinalTypeDef(node.type), typeId);
let newType = exposeArrayedType(node.items || csnUtils.getFinalTypeDef(node.type).items, typeId);
// When we have in the model something like:

@@ -258,3 +258,3 @@ // type Foo: array of Bar; type Bar: { qux: Integer };

function exposeArrayedType(typeDef, typeId) {
function exposeArrayedType(items, typeId) {
let newType = csn.definitions[typeId];

@@ -274,3 +274,3 @@ if (newType) {

// copy over the items
newType.items = cloneCsn(typeDef.items);
newType.items = cloneCsn(items);
csn.definitions[typeId] = newType;

@@ -290,3 +290,3 @@ exposedStructTypes.push(typeId);

if (csnUtils.isStructured(finalType)) {
def.items.elements = cloneCsn(finalType.elements);
if (!def.items.elements) def.items.elements = cloneCsn(finalType.elements);
delete def.items.type;

@@ -293,0 +293,0 @@ }

@@ -39,4 +39,4 @@ const {

* Return the definition name, without the prefixed service name
* @param {String} name
* @param {String} service
* @param {string} name
* @param {string} service
*/

@@ -51,4 +51,4 @@ function defNameWithoutServiceName(name, service) {

* name where the given artifact resides
* @param {String} artName
* @param {Array} services
* @param {string} artName
* @param {string[]} services
*/

@@ -72,4 +72,4 @@ function getServiceOfArtifact(artName, services) {

* the artifact is part of the service or not
* @param {String} artName
* @param {Array} services
* @param {string} artName
* @param {string[]} services
*/

@@ -84,4 +84,4 @@ function isArtifactInSomeService(artName, services) {

* the artifact is localized and part of the service
* @param {String} artName
* @param {Array} services
* @param {string} artName
* @param {string[]} services
*/

@@ -88,0 +88,0 @@ function isLocalizedArtifactInService(artName, services) {

@@ -558,3 +558,3 @@ 'use strict';

// Create the 'DRAFT.DraftAdministrativeData' entity
let artifact = {
const artifact = {
kind: 'entity',

@@ -561,0 +561,0 @@ elements: Object.create(null),

@@ -17,3 +17,3 @@ // Util functions for operations usually used with files.

module.exports = {
splitLines
}
splitLines,
};

@@ -1,22 +0,24 @@

///
/// This file is used for color output to stderr and stdout.
/// Use `term.error`, `term.warn` and `term.info` as they use color output
/// per default if the process runs in a TTY, i.e. stdout as well as
/// stderr are TTYs. stderr/stdout are no TTYs if they (for example)
/// are piped to another process or written to file:
///
/// node myapp.js # stdout.isTTY: true, stderr.isTTY: true
/// node myapp.js | cat # stdout.isTTY: undefined, stderr.isTTY: true
/// node myapp.js |& cat # stdout.isTTY: undefined, stderr.isTTY: undefined
/// node myapp.js > out.txt # stdout.isTTY: undefined, stderr.isTTY: true
/// node myapp.js 2> out.txt # stdout.isTTY: true, stderr.isTTY: undefined
///
//
// This file is used for color output to stderr and stdout.
// Use `term.error`, `term.warn` and `term.info` as they use color output
// per default if the process runs in a TTY, i.e. stdout as well as
// stderr are TTYs. stderr/stdout are no TTYs if they (for example)
// are piped to another process or written to file:
//
// node myapp.js # stdout.isTTY: true, stderr.isTTY: true
// node myapp.js | cat # stdout.isTTY: undefined, stderr.isTTY: true
// node myapp.js |& cat # stdout.isTTY: undefined, stderr.isTTY: undefined
// node myapp.js > out.txt # stdout.isTTY: undefined, stderr.isTTY: true
// node myapp.js 2> out.txt # stdout.isTTY: true, stderr.isTTY: undefined
//
const stderrHasColor = process.stderr.isTTY
const stdoutHasColor = process.stdout.isTTY
'use strict';
let hasColor = stdoutHasColor && stderrHasColor
const stderrHasColor = process.stderr.isTTY;
const stdoutHasColor = process.stdout.isTTY;
let hasColor = stdoutHasColor && stderrHasColor;
module.exports.useColor = (mode) => {
switch(mode) {
switch (mode) {
case false:

@@ -31,3 +33,3 @@ case 'never':

default:
hasColor = stdoutHasColor && stderrHasColor
hasColor = stdoutHasColor && stderrHasColor;
break;

@@ -38,3 +40,3 @@ }

// https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
const t = module.exports.codes = {
const t = {
reset: '\x1b[0m', // Default

@@ -48,17 +50,15 @@ bold: '\x1b[1m', // Bold/Bright

cyan: '\x1b[36m', // Foreground Cyan
}
};
const as = module.exports.as = (codes, o) => {
return hasColor ? (codes + o + t.reset) : ('' + o)
}
const as = (codes, o) => (hasColor ? (codes + o + t.reset) : (`${ o }`));
const asError = module.exports.error = o => as(t.red + t.bold, o)
const asWarning = module.exports.warn = o => as(t.yellow, o)
const asInfo = module.exports.info = o => as(t.green, o)
const asHelp = module.exports.help = o => as(t.cyan, o)
module.exports.underline = o => as(t.underline, o)
module.exports.bold = o => as(t.bold, o)
const asError = o => as(t.red + t.bold, o);
const asWarning = o => as(t.yellow, o);
const asInfo = o => as(t.green, o);
const asHelp = o => as(t.cyan, o);
module.exports.underline = o => as(t.underline, o);
module.exports.bold = o => as(t.bold, o);
module.exports.asSeverity = (severity, msg) => {
switch((severity + '').toLowerCase()) {
switch ((`${ severity }`).toLowerCase()) {
case 'error': return asError(msg);

@@ -71,2 +71,9 @@ case 'warning': return asWarning(msg);

}
}
};
module.exports.codes = t;
module.exports.as = as;
module.exports.error = asError;
module.exports.warn = asWarning;
module.exports.info = asInfo;
module.exports.help = asHelp;

@@ -0,1 +1,3 @@

'use strict';
/**

@@ -13,3 +15,3 @@ * A single TimeTrace encapsulates the runtime of a selected code frame.

*/
constructor(id){
constructor(id) {
let startTime;

@@ -21,7 +23,7 @@ /**

*/
this.start = function(indent){
this.start = function start(indent) {
// eslint-disable-next-line no-console
console.error(`${' '.repeat((indent)*2)}${id} started`);
console.error(`${ ' '.repeat((indent) * 2) }${ id } started`);
startTime = process.hrtime();
}
};

@@ -33,10 +35,10 @@ /**

*/
this.stop = function(indent){
this.stop = function stop(indent) {
const endTime = process.hrtime(startTime);
const base = `${' '.repeat(indent*2)}${id} took:`;
// eslint-disable-next-line no-console
console.error( `${base}${' '.repeat(60-base.length)} %ds %dms`, endTime[0], endTime[1] / 1000000);
}
const base = `${ ' '.repeat(indent * 2) }${ id } took:`;
// eslint-disable-next-line no-console
console.error( `${ base }${ ' '.repeat(60 - base.length) } %ds %dms`, endTime[0], endTime[1] / 1000000);
};
}
}
}

@@ -58,3 +60,3 @@ /**

*/
constructor(){
constructor() {
this.tracestack = [];

@@ -70,10 +72,12 @@ }

*/
start(id){
try{
start(id) {
try {
const b = new TimeTrace(id);
this.tracestack.push(b);
b.start(this.tracestack.length-1);
} catch(e){
console.error(`Starting time trace with id ${id} failed: ${e}`)
b.start(this.tracestack.length - 1);
}
catch (e) {
// eslint-disable-next-line no-console
console.error(`Starting time trace with id ${ id } failed: ${ e }`);
}
}

@@ -87,12 +91,15 @@

*/
stop(){
stop() {
try {
const current = this.tracestack.pop();
current.stop(this.tracestack.length);
} catch (e){
console.error(`Stopping time trace failed: ${e}`);
}
catch (e) {
// eslint-disable-next-line no-console
console.error(`Stopping time trace failed: ${ e }`);
}
}
}
module.exports = (process && process.env && process.env.CDSC_TIMETRACING !== undefined) ? new TimeTracer() : { start: () => {}, stop: () => {}};
const doTimeTrace = process && process.env && process.env.CDSC_TIMETRACING !== undefined;
module.exports = doTimeTrace ? new TimeTracer() : { start: () => {}, stop: () => {} };
{
"name": "@sap/cds-compiler",
"version": "1.42.2",
"version": "1.43.0",
"description": "CDS (Core Data Services) compiler and backends",

@@ -5,0 +5,0 @@ "homepage": "https://cap.cloud.sap/",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc