@sap/cds-compiler
Version:
CDS (Core Data Services) compiler and backends
126 lines (114 loc) • 4.56 kB
JavaScript
// Definitions for beta and deprecated options
// Normal options are in ../base/optionProcessor.js (and some other files),
// unfortunately partly non-grep-able (option `fooBar` is defined via `--foo-bar`)
;
/**
* Object of all available beta flags that will be enabled/disabled by `--beta-mode`
* through cdsc. Only intended for INTERNAL USE.
* NOT to be used by umbrella, etc.
*
* @type {{[flag: string]: boolean}} Indicates whether it is enabled by --beta-mode or not.
* @private
*/
const availableBetaFlags = {
// enabled by --beta-mode
hanaAssocRealCardinality: true,
mapAssocToJoinCardinality: true, // only SAP HANA HEX engine supports it
enableUniversalCsn: true,
odataTerms: true,
tenantVariable: true,
calcAssoc: true,
temporalRawProjection: true,
v8preview: true,
rewriteAnnotationExpressionsViaType: true,
sqlServiceDummies: true,
// disabled by --beta-mode
nestedServices: false,
};
// Used by isDeprecatedEnabled() to check if any flag ist set.
const availableDeprecatedFlags = {
// keep the following for a while:
downgradableErrors: true, // generally
ignoreSpecifiedQueryElements: true, // used by stakeholder
// remove/hide in a next release:
_noPersistenceJournalForGeneratedEntities: true, // since v6
_noCompositionIncludes: true, // since v6; was an option with inverted meaning in v5
noQuasiVirtualAssocs: true, // since v6
};
// Deprecated flags that were removed/hidden in newer version and are complained
// about with 'api-invalid-deprecated'. Keep all former availableDeprecatedFlags
// for two majors after they have been hidden (prefix _) or removed.
const oldDeprecatedFlags = {
// remove in v9:
noPersistenceJournalForGeneratedEntities: '7.0', // since v6
noCompositionIncludes: '7.0', // since v6
// remove in v8:
includesNonShadowedFirst: '6.0', // since v4
noKeyPropagationWithExpansions: '6.0', // since v4
eagerPersistenceForGeneratedEntities: '6.0', // since v3
};
/**
* Test for early-adaptor feature, stored in option `beta`(new-style) / `betaMode`(old-style)
* With that, the value of `beta` is a dictionary of feature=>Boolean.
*
* Beta features cannot be used when `options.deprecated` is set.
*
* A feature always needs to be provided - otherwise false will be returned.
*
* Do not move this function to the "option processor" code.
*
* @param {object} options Options
* @param {string} feature Feature to check for
* @returns {boolean}
*/
function isBetaEnabled( options, feature ) {
const beta = options.beta || options.betaMode;
return beta && typeof beta === 'object' && !options.deprecated && feature && beta[feature];
}
/**
* Test for deprecated feature, stored in option `deprecated`.
* With that, the value of `deprecated` is a dictionary of feature=>Boolean.
*
* If no `feature` is provided, checks if any deprecated option is set
* which is not mentioned in availableDeprecatedFlags with value true.
* Useful for newer functionality which might not work with some
* deprecated feature turned on.
*
* Do not move this function to the "option processor" code.
*
* @param {object} options Options
* @param {string|null} [feature] Feature to check for
* @returns {boolean}
*/
function isDeprecatedEnabled( options, feature = null ) {
const { deprecated } = options;
if (!feature) {
return !!deprecated && Object.keys( deprecated )
.some( d => !availableDeprecatedFlags[d] );
}
return deprecated && typeof deprecated === 'object' && deprecated[feature];
}
/**
* In the current cds-compiler, we might have removed old deprecated flags. That can lead to silent
* errors such as entity/view names changing. To ensure that the user is forced
* to change their code, emit an error if one of such removed flags was used.
*
* @param {CSN.Options} options
* @param error Error message function returned by makeMessageFunction().
*/
function checkRemovedDeprecatedFlags( { deprecated, messages }, { error } ) {
// Assume that we emitted these errors once if a message with this ID was found.
if (!deprecated || messages?.some( m => m.messageId === 'api-invalid-deprecated' ))
return;
Object.keys( deprecated ).forEach( ( key ) => {
const removed = oldDeprecatedFlags[key];
if (removed && deprecated[key] != null)
error( 'api-invalid-deprecated', null, { name: key, compiler: removed } );
});
}
module.exports = {
isBetaEnabled,
availableBetaFlags,
isDeprecatedEnabled,
checkRemovedDeprecatedFlags,
};