import { createLogger , ODataVersion } from '@sap-cloud-sdk/util' ; import { VdmNavigationProperty , VdmProperty , VdmServiceMetadata } from './vdm-types' ; const logger = createLogger ( { package : 'generator' , messageContext : 'generator-utils' } ) ; function hasCapability ( object , capability ) { return ! ( capability in object ) || object [ capability ] === 'true' ; } param entity returns internal export function isDeletable ( entity ) { return hasCapability ( entity , 'sap:deletable' ) ; } param entity returns internal export function isUpdatable ( entity ) { return hasCapability ( entity , 'sap:updatable' ) ; } param entity returns internal export function isCreatable ( entity ) { return hasCapability ( entity , 'sap:creatable' ) ; } param property returns internal export function isSortable ( property ) { return hasCapability ( property , 'sap:sortable' ) ; } param property returns internal export function isFilterable ( property ) { return hasCapability ( property , 'sap:filterable' ) ; } param property returns internal export function isNullableProperty ( property ) { return hasCapability ( property , 'Nullable' ) ; } param parameter returns internal export function isNullableParameter ( parameter ) { return ! ! parameter [ 'Nullable' ] && parameter [ 'Nullable' ] !== 'false' ; } internal export type EdmTypeMapping = { [ key in EdmTypeShared ] : string | undefined ; } ; type EdmTypeMappingWithoutEnum = { [ key in Exclude < EdmTypeShared , 'Edm.Enum' > ] : string | undefined ; } ; const edmToTsTypeMapping = { 'Edm.String' : 'string' , 'Edm.Boolean' : 'boolean' , 'Edm.Guid' : 'string' , 'Edm.Decimal' : 'BigNumber' , 'Edm.Int16' : 'number' , 'Edm.Int32' : 'number' , 'Edm.Int64' : 'BigNumber' , 'Edm.Single' : 'number' , 'Edm.Double' : 'number' , 'Edm.Float' : 'number' , 'Edm.Byte' : 'number' , 'Edm.SByte' : 'number' , 'Edm.DateTimeOffset' : 'Moment' , 'Edm.Binary' : 'string' , 'Edm.Any' : 'any' , 'Edm.DateTime' : 'Moment' , 'Edm.Time' : 'Time' , 'Edm.Date' : 'Moment' , 'Edm.Duration' : 'Duration' , 'Edm.TimeOfDay' : 'Time' } ; const edmToFieldTypeMapping = { 'Edm.String' : 'EdmTypeField' , 'Edm.Boolean' : 'EdmTypeField' , 'Edm.Guid' : 'EdmTypeField' , 'Edm.Decimal' : 'OrderableEdmTypeField' , 'Edm.Int16' : 'OrderableEdmTypeField' , 'Edm.Int32' : 'OrderableEdmTypeField' , 'Edm.Int64' : 'OrderableEdmTypeField' , 'Edm.Single' : 'OrderableEdmTypeField' , 'Edm.Double' : 'OrderableEdmTypeField' , 'Edm.Float' : 'OrderableEdmTypeField' , 'Edm.Byte' : 'OrderableEdmTypeField' , 'Edm.SByte' : 'OrderableEdmTypeField' , 'Edm.DateTimeOffset' : 'OrderableEdmTypeField' , 'Edm.Binary' : 'EdmTypeField' , 'Edm.Any' : 'EdmTypeField' , 'Edm.DateTime' : 'OrderableEdmTypeField' , 'Edm.Time' : 'OrderableEdmTypeField' , 'Edm.Date' : 'OrderableEdmTypeField' , 'Edm.Duration' : 'OrderableEdmTypeField' , 'Edm.TimeOfDay' : 'OrderableEdmTypeField' , 'Edm.Enum' : 'EdmTypeField' } ; internal export function getFallbackEdmTypeIfNeeded ( edmType ) { if ( edmType in edmToTsTypeMapping ) { return edmType as EdmTypeShared ; } logger . warn ( `The EDM type '${ edmType }' is unknown or not supported by the SAP Cloud SDK. Using "any" as fallback.` ) ; return 'Edm.Any' ; } internal export function edmToTsType ( edmType ) { const tsType = edmToTsTypeMapping [ edmType ] ; if ( ! tsType ) { throw new Error ( `Could not determine TypeScript type for EDM type: '${ edmType }'.` ) ; } return tsType ; } internal export function edmToFieldType ( edmType ) { const fieldType = edmToFieldTypeMapping [ edmType ] ; if ( ! fieldType ) { throw new Error ( `Could not determine field type for EDM type: '${ edmType }'.` ) ; } return fieldType ; } internal export function edmToComplexPropertyType ( edmType ) { const fieldType = edmToFieldType ( edmType ) ; if ( ! fieldType ) { throw new Error ( `Could not determine complex field type for EDM type: '${ edmType }'.` ) ; } return fieldType ; } internal export function forceArray ( obj ) { if ( ! obj ) { return [ ] ; } if ( ! ( obj instanceof Array ) ) { return [ obj ] ; } return obj ; } internal export function ensureString ( obj ) { if ( typeof obj === 'undefined' || obj === null ) { return '' ; } if ( typeof obj === 'string' ) { return obj ; } return `${ obj }` ; } internal export function endWithDot ( text ) { return ! text || text . endsWith ( '.' ) || text . endsWith ( ':' ) ? text : `${ text }.` ; } internal export function linkClass ( navProperty , oDataVersion ) { return navProperty . isCollection ? oDataVersion === 'v4' ? 'OneToManyLink' : 'Link' : 'OneToOneLink' ; } internal export function getGenericParameters ( entityClassName , prop , isSelectable ) { const params = [ entityClassName , 'DeSerializersT' ] ; if ( prop . isCollection ) { if ( prop . isEnum ) { params . push ( `typeof ${ prop . jsType }` ) ; } else if ( prop . isComplex ) { params . push ( prop . jsType ) ; } else { params . push ( `'${ prop . edmType }'` ) ; } } else { if ( prop . isEnum ) { params . push ( `${ prop . jsType }` ) ; } else if ( prop . isComplex ) { } else { params . push ( `'${ prop . edmType }'` ) ; } } params . push ( prop . nullable . toString ( ) ) ; params . push ( isSelectable . toString ( ) ) ; return params . join ( ', ' ) ; } param string param prefix returns internal export function prefixString ( string , prefix ? ) { return prefix ? `${ prefix }${ string }` : string ; } param name returns internal export function npmCompliantName ( name ) { let compliantName = trimToNpmMaxLength ( name ) ; compliantName = transformIfNecessary ( compliantName ) ; return compliantName ; } internal export function cloudSdkVdmHack ( name ) { return name === '@sap/cloud-sdk-vdm-' ? name . slice ( 0 , - 1 ) : name ; } const trimToNpmMaxLength = ( str ) : string => { if ( str . length > npmMaxLength ) { logger . warn ( `Provided package name ${ str } is longer than 214 chars and will be cut!` ) ; return str . substr ( 0 , npmMaxLength ) ; } return str ; } ; const transformIfNecessary = ( packageName ) : string => { if ( npmRegex . exec ( packageName ) ) { return packageName ; } const newName = _npmCompliantName ( packageName ) ; logger . warn ( `Provided name ${ packageName } is not compliant with npm naming rules and was transformed to ${ newName }!` ) ; return newName ; } ; const _npmCompliantName = ( name ) : string => { if ( name . startsWith ( '@' ) && name . includes ( '/' ) ) { return ( '@' + splitAtFirstOccurrence ( name , '/' ) . map ( x => makeNpmCompliant ( x ) ) . join ( '/' ) ) ; } return makeNpmCompliant ( name ) ; } ; const splitAtFirstOccurrence = ( str , separator ) => [ str . slice ( 0 , str . indexOf ( separator ) ) , str . slice ( str . indexOf ( separator ) + 1 ) ] ; const lowerCase = ( str ) : string => str . toLowerCase ( ) ; const stripLeadingDotsAndUnderscores = ( str ) : string => str . replace ( /^[._]*/g , '' ) ; const replaceNonNpmPackageCharacters = ( str ) : string => str . replace ( /[^a-z0-9-~._]/g , '' ) ; const makeNpmCompliant = ( name ) => { let compliantName = lowerCase ( name ) ; compliantName = stripLeadingDotsAndUnderscores ( compliantName ) ; compliantName = replaceNonNpmPackageCharacters ( compliantName ) ; return compliantName ; } ; const npmMaxLength = 214 ; const npmRegex = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/ ; internal export function hasEntities ( service ) { return ! ! service . entities ?. length ; } internal export type EdmTypeShared = 'Edm.String' | 'Edm.Boolean' | 'Edm.Decimal' | 'Edm.Double' | 'Edm.Single' | 'Edm.Float' | 'Edm.Int16' | 'Edm.Int32' | 'Edm.Int64' | 'Edm.SByte' | 'Edm.Binary' | 'Edm.Guid' | 'Edm.Byte' | 'Edm.Any' | 'Edm.DateTimeOffset' | 'Edm.DateTime' | 'Edm.Time' | 'Edm.Date' | 'Edm.Duration' | 'Edm.TimeOfDay' | 'Edm.Enum' ;