@sap/cds-compiler 5.9.4 → 6.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -319
- package/README.md +1 -1
- package/bin/cds_update_identifiers.js +3 -5
- package/bin/cdsc.js +24 -9
- package/bin/cdshi.js +1 -1
- package/bin/cdsse.js +4 -4
- package/doc/CHANGELOG_BETA.md +11 -0
- package/doc/CHANGELOG_DEPRECATED.md +29 -0
- package/lib/api/main.js +8 -5
- package/lib/api/options.js +12 -10
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +191 -99
- package/lib/base/messages.js +35 -21
- package/lib/base/model.js +14 -24
- package/lib/checks/actionsFunctions.js +10 -20
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/elements.js +35 -10
- package/lib/checks/enums.js +31 -0
- package/lib/checks/foreignKeys.js +2 -2
- package/lib/checks/hasPersistedElements.js +5 -0
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedWithoutKeys.js +5 -4
- package/lib/checks/queryNoDbArtifacts.js +10 -8
- package/lib/checks/types.js +5 -5
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +13 -9
- package/lib/compiler/checks.js +20 -52
- package/lib/compiler/define.js +31 -6
- package/lib/compiler/extend.js +5 -1
- package/lib/compiler/generate.js +14 -17
- package/lib/compiler/populate.js +8 -31
- package/lib/compiler/propagator.js +21 -35
- package/lib/compiler/resolve.js +64 -29
- package/lib/compiler/shared.js +16 -4
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +1 -1
- package/lib/edm/annotations/edmJson.js +23 -20
- package/lib/edm/annotations/genericTranslation.js +12 -10
- package/lib/edm/csn2edm.js +50 -56
- package/lib/edm/edm.js +33 -28
- package/lib/edm/edmInboundChecks.js +2 -2
- package/lib/edm/edmPreprocessor.js +54 -88
- package/lib/edm/edmUtils.js +9 -12
- package/lib/gen/BaseParser.js +63 -52
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1153 -1165
- package/lib/gen/Dictionary.json +21 -1
- package/lib/json/from-csn.js +70 -43
- package/lib/json/to-csn.js +6 -8
- package/lib/language/multiLineStringParser.js +3 -2
- package/lib/main.d.ts +58 -24
- package/lib/model/cloneCsn.js +3 -0
- package/lib/model/csnUtils.js +28 -39
- package/lib/model/xprAsTree.js +23 -9
- package/lib/modelCompare/compare.js +5 -4
- package/lib/optionProcessor.js +24 -17
- package/lib/parsers/AstBuildingParser.js +81 -25
- package/lib/parsers/XprTree.js +57 -3
- package/lib/parsers/identifiers.js +1 -1
- package/lib/parsers/index.js +0 -3
- package/lib/render/manageConstraints.js +25 -25
- package/lib/render/toCdl.js +173 -170
- package/lib/render/toHdbcds.js +126 -128
- package/lib/render/toRename.js +7 -7
- package/lib/render/toSql.js +128 -125
- package/lib/render/utils/common.js +47 -22
- package/lib/render/utils/delta.js +25 -25
- package/lib/render/utils/operators.js +2 -2
- package/lib/render/utils/pretty.js +5 -5
- package/lib/render/utils/sql.js +13 -13
- package/lib/render/utils/standardDatabaseFunctions.js +115 -103
- package/lib/render/utils/unique.js +4 -4
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +2 -2
- package/lib/transform/db/associations.js +6 -7
- package/lib/transform/db/assocsToQueries/utils.js +4 -5
- package/lib/transform/db/backlinks.js +12 -9
- package/lib/transform/db/cdsPersistence.js +8 -7
- package/lib/transform/db/constraints.js +13 -10
- package/lib/transform/db/expansion.js +7 -3
- package/lib/transform/db/flattening.js +4 -14
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/temporal.js +5 -7
- package/lib/transform/db/views.js +2 -4
- package/lib/transform/draft/db.js +8 -8
- package/lib/transform/draft/odata.js +10 -7
- package/lib/transform/forOdata.js +10 -5
- package/lib/transform/forRelationalDB.js +5 -75
- package/lib/transform/localized.js +1 -1
- package/lib/transform/odata/createForeignKeys.js +11 -10
- package/lib/transform/odata/flattening.js +8 -4
- package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/transformUtils.js +4 -8
- package/lib/transform/translateAssocsToJoins.js +14 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
- package/lib/utils/objectUtils.js +0 -17
- package/package.json +10 -13
- package/share/messages/def-upcoming-virtual-change.md +1 -1
- package/LICENSE +0 -37
- package/bin/cds_remove_invalid_whitespace.js +0 -138
- package/doc/CHANGELOG_ARCHIVE.md +0 -3604
- package/lib/gen/genericAntlrParser.js +0 -3
- package/lib/gen/language.checksum +0 -1
- package/lib/gen/language.interp +0 -456
- package/lib/gen/language.tokens +0 -180
- package/lib/gen/languageLexer.interp +0 -439
- package/lib/gen/languageLexer.js +0 -1483
- package/lib/gen/languageLexer.tokens +0 -167
- package/lib/gen/languageParser.js +0 -24941
- package/lib/language/antlrParser.js +0 -205
- package/lib/language/errorStrategy.js +0 -646
- package/lib/language/genericAntlrParser.js +0 -1572
- package/lib/parsers/CdlGrammar.g4 +0 -2070
package/lib/edm/csn2edm.js
CHANGED
|
@@ -79,7 +79,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
79
79
|
|
|
80
80
|
const mergedVocabularies = translate.mergeOdataVocabularies(options, message);
|
|
81
81
|
|
|
82
|
-
const Edm = getEdm(options
|
|
82
|
+
const Edm = getEdm(options);
|
|
83
83
|
|
|
84
84
|
const { v } = options;
|
|
85
85
|
if (Object.keys(allServices).length === 0) {
|
|
@@ -304,14 +304,13 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
304
304
|
|
|
305
305
|
const usages = UsedTypes[typeName].filter(u => !u.$NameClashReported);
|
|
306
306
|
if (usages.length > 0 && def && !def.$isRendered && def['@cds.external']) {
|
|
307
|
-
message('odata-
|
|
307
|
+
message('odata-invalid-external-type', usages[0].$location,
|
|
308
308
|
{
|
|
309
309
|
type: typeName,
|
|
310
310
|
anno: '@cds.external',
|
|
311
311
|
name: serviceCsn.name,
|
|
312
312
|
code: def.elements ? 'Edm.ComplexType' : 'Edm.TypeDefinition',
|
|
313
313
|
version: options.isV4() ? '4.0' : '2.0',
|
|
314
|
-
'#': 'external',
|
|
315
314
|
});
|
|
316
315
|
}
|
|
317
316
|
}
|
|
@@ -407,14 +406,14 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
407
406
|
const reservedNames = [ 'Edm', 'odata', 'System', 'Transient' ];
|
|
408
407
|
const loc = [ 'definitions', schema.name ];
|
|
409
408
|
if (reservedNames.includes(schema.name))
|
|
410
|
-
message('odata-
|
|
409
|
+
message('odata-invalid-service-name', loc, { names: reservedNames });
|
|
411
410
|
if (schema.name.length > 511) {
|
|
412
|
-
message('odata-
|
|
411
|
+
message('odata-invalid-service-name', loc, { '#': 'length' });
|
|
413
412
|
}
|
|
414
413
|
else {
|
|
415
414
|
schema.name.split('.').forEach((id) => {
|
|
416
415
|
if (!edmUtils.isODataSimpleIdentifier(id))
|
|
417
|
-
message('odata-
|
|
416
|
+
message('odata-invalid-name', loc, { id });
|
|
418
417
|
});
|
|
419
418
|
}
|
|
420
419
|
|
|
@@ -523,29 +522,31 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
523
522
|
// this especially covers: 'items: composition of one { data : String; }'
|
|
524
523
|
// "keyless" composition targets in structured containment mode
|
|
525
524
|
else if (entityCsn.$hasEntitySet && entityCsn.$edmKeyPaths.length === 0 && !isSingleton)
|
|
526
|
-
message('odata-
|
|
525
|
+
message('odata-missing-key', location);
|
|
527
526
|
|
|
528
527
|
if (!edmUtils.isODataSimpleIdentifier(EntityTypeName))
|
|
529
|
-
message('odata-
|
|
528
|
+
message('odata-invalid-name', location, { id: EntityTypeName });
|
|
530
529
|
|
|
531
530
|
properties.forEach((p) => {
|
|
532
531
|
const pLoc = [ ...location, 'elements', p._edmAttributes.Name ];
|
|
533
532
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
534
533
|
if (p._edmAttributes.Name === EntityTypeName)
|
|
535
|
-
message('odata-
|
|
534
|
+
message('odata-invalid-property-name', pLoc, { meta: entityCsn.kind });
|
|
536
535
|
|
|
537
536
|
if (options.isV2() && p.$isCollection && !p._csn.target)
|
|
538
|
-
message('odata-
|
|
537
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
539
538
|
|
|
540
539
|
if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name)) {
|
|
541
|
-
message('odata-
|
|
540
|
+
message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
|
|
542
541
|
}
|
|
543
542
|
else if (options.isV2() && /^(_|\d)/.test(p._edmAttributes.Name)) {
|
|
544
543
|
// FIXME: Rewrite signalIllegalIdentifier function to be more flexible
|
|
545
|
-
message('odata-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
544
|
+
message('odata-invalid-name', pLoc, {
|
|
545
|
+
'#': 'v2firstChar',
|
|
546
|
+
prop: p._edmAttributes.Name[0],
|
|
547
|
+
id: p._edmAttributes.Name,
|
|
548
|
+
version: '2.0',
|
|
549
|
+
});
|
|
549
550
|
}
|
|
550
551
|
});
|
|
551
552
|
|
|
@@ -603,23 +604,23 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
603
604
|
const location = [ 'definitions', structuredTypeCsn.name ];
|
|
604
605
|
|
|
605
606
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
606
|
-
message('odata-
|
|
607
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
607
608
|
|
|
608
609
|
properties.forEach((p) => {
|
|
609
610
|
const pLoc = [ ...location, ...(structuredTypeCsn.items ? [ 'items', 'elements' ] : [ 'elements' ]), p._edmAttributes.Name ];
|
|
610
611
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
611
612
|
if (p._edmAttributes.Name === complexType._edmAttributes.Name)
|
|
612
|
-
message('odata-
|
|
613
|
+
message('odata-invalid-property-name', pLoc, { meta: structuredTypeCsn.kind });
|
|
613
614
|
|
|
614
615
|
if (!edmUtils.isODataSimpleIdentifier(p._edmAttributes.Name))
|
|
615
|
-
message('odata-
|
|
616
|
+
message('odata-invalid-name', pLoc, { id: p._edmAttributes.Name });
|
|
616
617
|
|
|
617
618
|
if (options.isV2()) {
|
|
618
619
|
if (p.$isCollection && !p._csn.target)
|
|
619
|
-
message('odata-
|
|
620
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
620
621
|
|
|
621
622
|
if (p._csn.target)
|
|
622
|
-
message('odata-
|
|
623
|
+
message('odata-unexpected-assoc', pLoc, { version: '2.0' });
|
|
623
624
|
}
|
|
624
625
|
});
|
|
625
626
|
|
|
@@ -713,7 +714,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
713
714
|
// derived types are already resolved to base types
|
|
714
715
|
const attributes = { Name: typeCsn.name.replace(schemaNamePrefix, '') };
|
|
715
716
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
716
|
-
message('odata-
|
|
717
|
+
message('odata-invalid-name', typeCsn.$path, { id: attributes.Name });
|
|
717
718
|
|
|
718
719
|
const typeDef = new Edm.TypeDefinition(v, attributes, typeCsn );
|
|
719
720
|
edmTypeCompatibilityCheck(typeDef, typeCsn.$path);
|
|
@@ -732,7 +733,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
732
733
|
|
|
733
734
|
|
|
734
735
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
735
|
-
message('odata-
|
|
736
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
736
737
|
|
|
737
738
|
if (!iAmAnAction)
|
|
738
739
|
attributes.IsComposable = false;
|
|
@@ -766,7 +767,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
766
767
|
setProp(firstParam, '_edmType', bpType);
|
|
767
768
|
}
|
|
768
769
|
if (!edmUtils.isODataSimpleIdentifier(bpName))
|
|
769
|
-
message('odata-
|
|
770
|
+
message('odata-invalid-name', [ ...location, 'params', bpName ], { id: bpName });
|
|
770
771
|
}
|
|
771
772
|
}
|
|
772
773
|
|
|
@@ -795,7 +796,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
795
796
|
}
|
|
796
797
|
|
|
797
798
|
if (!edmUtils.isODataSimpleIdentifier(bpName))
|
|
798
|
-
message('odata-
|
|
799
|
+
message('odata-invalid-name', bpnAnnoLoc, { id: bpName });
|
|
799
800
|
if (actionCsn.params && actionCsn.params[bpName])
|
|
800
801
|
error('duplicate-definition', bpnAnnoLoc, { '#': 'param', name: bpName });
|
|
801
802
|
}
|
|
@@ -839,7 +840,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
839
840
|
const p = new Edm.Parameter(v, { Name: parameterName }, parameterCsn );
|
|
840
841
|
const pLoc = [ ...location, 'params', p._edmAttributes.Name ];
|
|
841
842
|
if (!edmUtils.isODataSimpleIdentifier(parameterName))
|
|
842
|
-
message('odata-
|
|
843
|
+
message('odata-invalid-name', pLoc, { id: parameterName });
|
|
843
844
|
collectUsedType(parameterCsn);
|
|
844
845
|
edmTypeCompatibilityCheck(p, pLoc);
|
|
845
846
|
actionNode.append(p);
|
|
@@ -880,7 +881,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
880
881
|
: [ 'definitions', actionCsn.name ];
|
|
881
882
|
|
|
882
883
|
if (!edmUtils.isODataSimpleIdentifier(attributes.Name))
|
|
883
|
-
message('odata-
|
|
884
|
+
message('odata-invalid-name', location, { id: attributes.Name });
|
|
884
885
|
|
|
885
886
|
const rt = actionCsn.returns && ((actionCsn.returns.items && actionCsn.returns.items.type) || actionCsn.returns.type);
|
|
886
887
|
if (rt) { // add EntitySet attribute only if return type is an entity
|
|
@@ -936,17 +937,17 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
936
937
|
collectUsedType(parameterCsn);
|
|
937
938
|
edmTypeCompatibilityCheck(param, pLoc);
|
|
938
939
|
if (!edmUtils.isODataSimpleIdentifier(parameterName))
|
|
939
|
-
message('odata-
|
|
940
|
+
message('odata-invalid-name', pLoc, { id: parameterName });
|
|
940
941
|
|
|
941
942
|
// only scalar or structured type in V2 (not entity)
|
|
942
943
|
if (param._type &&
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
message('odata-
|
|
944
|
+
!param._type.startsWith('Edm.') &&
|
|
945
|
+
csn.definitions[param._type] &&
|
|
946
|
+
!edmUtils.isStructuredType(csn.definitions[param._type]))
|
|
947
|
+
message('odata-invalid-param-type', pLoc, { version: '2.0' });
|
|
947
948
|
|
|
948
949
|
if (param.$isCollection)
|
|
949
|
-
message('odata-
|
|
950
|
+
message('odata-unexpected-array', pLoc, { version: '2.0' });
|
|
950
951
|
|
|
951
952
|
functionImport.append(param);
|
|
952
953
|
}
|
|
@@ -966,27 +967,26 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
966
967
|
if (type) {
|
|
967
968
|
collectUsedType(action.returns);
|
|
968
969
|
if (!isBuiltinType(type) && csn.definitions[type].kind !== 'entity' && csn.definitions[type].kind !== 'type') {
|
|
969
|
-
message('odata-
|
|
970
|
+
message('odata-invalid-return-type', returnsLoc, { kind: action.kind, version: '2.0' });
|
|
970
971
|
}
|
|
971
972
|
else if (isBuiltinType(type)) {
|
|
972
973
|
type = edmUtils.mapCdsToEdmType(returns, messageFunctions, _options);
|
|
973
974
|
if (type) {
|
|
974
975
|
const td = EdmPrimitiveTypeMap[type];
|
|
975
976
|
if (td && !td.v2) {
|
|
976
|
-
message('odata-
|
|
977
|
-
{ type, version: '2.0'
|
|
977
|
+
message('odata-unexpected-edm-type', returnsLoc,
|
|
978
|
+
{ type, version: '2.0' });
|
|
978
979
|
}
|
|
979
980
|
}
|
|
980
981
|
else {
|
|
981
|
-
message('odata-
|
|
982
|
+
message('odata-unknown-edm-type', returnsLoc, { type });
|
|
982
983
|
}
|
|
983
984
|
}
|
|
984
985
|
if (action.returns.$isCollection)
|
|
985
986
|
type = `Collection(${ type })`;
|
|
986
987
|
}
|
|
987
988
|
else {
|
|
988
|
-
|
|
989
|
-
message('odata-spec-violation-type', returnsLoc);
|
|
989
|
+
message('odata-missing-type', returnsLoc);
|
|
990
990
|
}
|
|
991
991
|
}
|
|
992
992
|
return type;
|
|
@@ -1159,7 +1159,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
1159
1159
|
function edmTypeCompatibilityCheck( p, pLoc ) {
|
|
1160
1160
|
const edmType = p._type;
|
|
1161
1161
|
if (!edmType) {
|
|
1162
|
-
message('odata-
|
|
1162
|
+
message('odata-missing-type', pLoc);
|
|
1163
1163
|
}
|
|
1164
1164
|
else if (p._scalarType) {
|
|
1165
1165
|
const td = EdmPrimitiveTypeMap[edmType];
|
|
@@ -1167,41 +1167,35 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
|
|
|
1167
1167
|
// The renderer/type mapper doesn't/shouldn't produce incompatible types and facets.
|
|
1168
1168
|
// Only the unknown type warning may be triggered by an unknown @odata.Type override.
|
|
1169
1169
|
if (td.v2 !== p.v2 && td.v4 !== p.v4) {
|
|
1170
|
-
message('odata-
|
|
1171
|
-
{ type: edmType, version: (p.v4 ? '4.0' : '2.0')
|
|
1170
|
+
message('odata-unexpected-edm-type', pLoc,
|
|
1171
|
+
{ type: edmType, version: (p.v4 ? '4.0' : '2.0') });
|
|
1172
1172
|
}
|
|
1173
1173
|
EdmTypeFacetNames.forEach((name) => {
|
|
1174
1174
|
const facet = EdmTypeFacetMap[name];
|
|
1175
|
-
const optional
|
|
1176
|
-
|
|
1177
|
-
?
|
|
1178
|
-
|
|
1179
|
-
: facet.optional)
|
|
1180
|
-
: false;
|
|
1175
|
+
const optional = (facet.optional !== undefined) &&
|
|
1176
|
+
(Array.isArray(facet.optional)
|
|
1177
|
+
? facet.optional.includes(edmType)
|
|
1178
|
+
: facet.optional);
|
|
1181
1179
|
|
|
1182
1180
|
// facet is not in attributes
|
|
1183
1181
|
// facet is member of type definition and mandatory
|
|
1184
1182
|
// node and facet version match
|
|
1185
1183
|
if (!p._edmAttributes[name] && td[name] && !optional && (p.v2 === facet.v2 || p.v4 === facet.v4)) {
|
|
1186
|
-
message('odata-
|
|
1187
|
-
{
|
|
1188
|
-
type: edmType, name, version: (p.v4 ? '4.0' : '2.0'), '#': 'facet',
|
|
1189
|
-
});
|
|
1184
|
+
message('odata-unexpected-edm-facet', pLoc,
|
|
1185
|
+
{ type: edmType, name, version: (p.v4 ? '4.0' : '2.0') });
|
|
1190
1186
|
}
|
|
1191
1187
|
});
|
|
1192
1188
|
if (edmType === 'Edm.Decimal') {
|
|
1193
1189
|
const precision = Number.parseInt(p._edmAttributes.Precision, 10);
|
|
1194
1190
|
const scale = Number.parseInt(p._edmAttributes.Scale, 10);
|
|
1195
1191
|
if (!Number.isNaN(precision) && !Number.isNaN(scale) && scale > precision) {
|
|
1196
|
-
message('odata-
|
|
1197
|
-
{
|
|
1198
|
-
type: edmType, number: scale, rawvalue: precision, '#': 'scale',
|
|
1199
|
-
});
|
|
1192
|
+
message('odata-invalid-scale', pLoc,
|
|
1193
|
+
{ number: scale, rawvalue: precision });
|
|
1200
1194
|
}
|
|
1201
1195
|
}
|
|
1202
1196
|
}
|
|
1203
1197
|
else {
|
|
1204
|
-
message('odata-
|
|
1198
|
+
message('odata-unknown-edm-type', pLoc, { type: edmType });
|
|
1205
1199
|
}
|
|
1206
1200
|
}
|
|
1207
1201
|
}
|
package/lib/edm/edm.js
CHANGED
|
@@ -8,9 +8,9 @@ const {
|
|
|
8
8
|
EdmTypeFacetNames,
|
|
9
9
|
EdmPrimitiveTypeMap,
|
|
10
10
|
} = require('./EdmPrimitiveTypeDefinitions.js');
|
|
11
|
+
const { CompilerAssertion } = require('../base/error');
|
|
11
12
|
|
|
12
|
-
function getEdm( options
|
|
13
|
-
const { error } = messageFunctions || { error: () => true, warning: () => true };
|
|
13
|
+
function getEdm( options ) {
|
|
14
14
|
class Node {
|
|
15
15
|
/**
|
|
16
16
|
* @param {boolean[]} version Versions in the form of [<v2>, <v4>].
|
|
@@ -19,11 +19,11 @@ function getEdm( options, messageFunctions ) {
|
|
|
19
19
|
*/
|
|
20
20
|
constructor(version, attributes = Object.create(null), csn = undefined) {
|
|
21
21
|
if (!attributes || typeof attributes !== 'object')
|
|
22
|
-
|
|
22
|
+
throw new CompilerAssertion('Debug me: attributes must be a dictionary');
|
|
23
23
|
if (!Array.isArray(version))
|
|
24
|
-
|
|
24
|
+
throw new CompilerAssertion(`Debug me: v is either undefined or not an array: ${ version }`);
|
|
25
25
|
if (version.filter(v => v).length !== 1)
|
|
26
|
-
|
|
26
|
+
throw new CompilerAssertion('Debug me: exactly one version must be set');
|
|
27
27
|
|
|
28
28
|
// Common attributes of JSON and XML.
|
|
29
29
|
// Note: Can't assign attributes directly, due to the input object being modified.
|
|
@@ -633,17 +633,17 @@ function getEdm( options, messageFunctions ) {
|
|
|
633
633
|
this._typeName = typeName;
|
|
634
634
|
this._scalarType = undefined;
|
|
635
635
|
if (this._edmAttributes[typeName] === undefined) {
|
|
636
|
-
const
|
|
636
|
+
const typeCsn = csn.items?.type ? csn.items : csn;
|
|
637
637
|
// Complex/EntityType are derived from TypeBase
|
|
638
638
|
// but have no type attribute in their CSN
|
|
639
|
-
if (
|
|
639
|
+
if (typeCsn.type) { // this thing has a type
|
|
640
640
|
// check whether this is a scalar type (or array of scalar type) or a named type
|
|
641
|
-
if (
|
|
642
|
-
isBuiltinType(
|
|
643
|
-
this._scalarType =
|
|
641
|
+
if (typeCsn.items?.type &&
|
|
642
|
+
isBuiltinType(typeCsn.items.type))
|
|
643
|
+
this._scalarType = typeCsn.items;
|
|
644
644
|
|
|
645
|
-
else if (isBuiltinType(
|
|
646
|
-
this._scalarType =
|
|
645
|
+
else if (isBuiltinType(typeCsn.type))
|
|
646
|
+
this._scalarType = typeCsn;
|
|
647
647
|
|
|
648
648
|
if (this._scalarType) {
|
|
649
649
|
this._edmAttributes[typeName] = csn._edmType;
|
|
@@ -658,7 +658,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
658
658
|
}
|
|
659
659
|
else {
|
|
660
660
|
// it's either _edmType or type (_edmType only used for explicit binding param)
|
|
661
|
-
this._edmAttributes[typeName] =
|
|
661
|
+
this._edmAttributes[typeName] = typeCsn._edmType || typeCsn.type;
|
|
662
662
|
}
|
|
663
663
|
}
|
|
664
664
|
// CDXCORE-245:
|
|
@@ -666,7 +666,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
666
666
|
// optionally add @odata { MaxLength, Precision, Scale, SRID }
|
|
667
667
|
// but only in combination with @odata.Type
|
|
668
668
|
// Allow to override type only on scalar and undefined types
|
|
669
|
-
if ((this._scalarType ||
|
|
669
|
+
if ((this._scalarType || typeCsn.type == null) && !csn.elements) {
|
|
670
670
|
const odataType = csn['@odata.Type'];
|
|
671
671
|
if (odataType) {
|
|
672
672
|
const td = EdmPrimitiveTypeMap[odataType];
|
|
@@ -741,6 +741,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
741
741
|
this._edmAttributes.OpenType = true;
|
|
742
742
|
}
|
|
743
743
|
}
|
|
744
|
+
|
|
744
745
|
class EntityType extends ComplexType {
|
|
745
746
|
constructor(version, details, properties, csn) {
|
|
746
747
|
super(version, details, csn);
|
|
@@ -1052,15 +1053,15 @@ function getEdm( options, messageFunctions ) {
|
|
|
1052
1053
|
delete this._edmAttributes.Nullable;
|
|
1053
1054
|
}
|
|
1054
1055
|
// we have exactly one selfReference or the default partner
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1056
|
+
|
|
1057
|
+
if ( !csn.$noPartner) {
|
|
1058
|
+
const partner = csn._selfReferences.length === 1
|
|
1059
|
+
? csn._selfReferences[0]
|
|
1060
|
+
: csn._constraints._partnerCsn;
|
|
1061
|
+
if (partner && partner['@odata.navigable'] !== false && this._csn._edmParentCsn.kind !== 'type') {
|
|
1062
|
+
// $abspath[0] is main entity
|
|
1063
|
+
this._edmAttributes.Partner = partner.$abspath.slice(1).join('/');
|
|
1064
|
+
}
|
|
1064
1065
|
}
|
|
1065
1066
|
|
|
1066
1067
|
/*
|
|
@@ -1142,7 +1143,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
1142
1143
|
json.$OnDelete = c._edmAttributes.Action;
|
|
1143
1144
|
break;
|
|
1144
1145
|
default:
|
|
1145
|
-
|
|
1146
|
+
throw new CompilerAssertion(`Debug me: Unhandled NavProp child: ${ c.kind }`);
|
|
1146
1147
|
}
|
|
1147
1148
|
});
|
|
1148
1149
|
// TODO Annotations
|
|
@@ -1211,8 +1212,11 @@ function getEdm( options, messageFunctions ) {
|
|
|
1211
1212
|
/* short notation for Edm.Boolean, Edm.String and Edm.Float, see internal project:
|
|
1212
1213
|
edmx2csn-npm/edm-converters/blob/835d92a1aa6b0be25c56cef85e260c9188187429/lib/edmxV40ToJsonV40/README.md
|
|
1213
1214
|
*/
|
|
1214
|
-
if (inline[0] === 'Edm.Boolean')
|
|
1215
|
-
|
|
1215
|
+
if (inline[0] === 'Edm.Boolean') {
|
|
1216
|
+
if (v === 'true')
|
|
1217
|
+
return true;
|
|
1218
|
+
return (v === 'false') ? false : v;
|
|
1219
|
+
}
|
|
1216
1220
|
return v;
|
|
1217
1221
|
}
|
|
1218
1222
|
|
|
@@ -1291,7 +1295,8 @@ function getEdm( options, messageFunctions ) {
|
|
|
1291
1295
|
}
|
|
1292
1296
|
|
|
1293
1297
|
getJsonFQTermName() {
|
|
1294
|
-
|
|
1298
|
+
const qualifier = this._edmAttributes.Qualifier ? `#${ this._edmAttributes.Qualifier }` : '';
|
|
1299
|
+
return `@${ this._edmAttributes.Term }${ qualifier }`;
|
|
1295
1300
|
}
|
|
1296
1301
|
}
|
|
1297
1302
|
|
|
@@ -1340,7 +1345,7 @@ function getEdm( options, messageFunctions ) {
|
|
|
1340
1345
|
break;
|
|
1341
1346
|
}
|
|
1342
1347
|
default:
|
|
1343
|
-
|
|
1348
|
+
throw new CompilerAssertion(`Debug me: Unhandled Record child: ${ c.kind }`);
|
|
1344
1349
|
}
|
|
1345
1350
|
});
|
|
1346
1351
|
return json;
|
|
@@ -117,13 +117,13 @@ function inboundQualificationChecks( csn, options, messageFunctions,
|
|
|
117
117
|
i++;
|
|
118
118
|
}
|
|
119
119
|
if (i > 1) {
|
|
120
|
-
message('
|
|
120
|
+
message('type-invalid-items', path, { '#': 'nested', prop: 'items' });
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
const itemsType = csnUtils.effectiveType(memberType.items);
|
|
125
125
|
if (itemsType.items)
|
|
126
|
-
message('
|
|
126
|
+
message('type-invalid-items', path, { '#': 'chained-service', prop: 'items' });
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|