@sap/cds-compiler 2.13.8 → 3.0.0
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 +155 -1594
- package/bin/cdsc.js +144 -66
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +237 -122
- package/lib/api/options.js +17 -88
- package/lib/api/validate.js +12 -16
- package/lib/base/keywords.js +216 -109
- package/lib/base/message-registry.js +152 -37
- package/lib/base/messages.js +145 -83
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +19 -0
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +11 -32
- package/lib/checks/arrayOfs.js +1 -34
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +4 -5
- package/lib/compiler/assert-consistency.js +16 -10
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +98 -9
- package/lib/compiler/checks.js +22 -70
- package/lib/compiler/define.js +61 -13
- package/lib/compiler/extend.js +79 -14
- package/lib/compiler/finalize-parse-cdl.js +46 -29
- package/lib/compiler/index.js +100 -37
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +19 -18
- package/lib/compiler/propagator.js +7 -4
- package/lib/compiler/resolve.js +297 -234
- package/lib/compiler/shared.js +107 -102
- package/lib/compiler/tweak-assocs.js +16 -11
- package/lib/compiler/utils.js +5 -0
- package/lib/edm/annotations/genericTranslation.js +93 -21
- package/lib/edm/csn2edm.js +230 -115
- package/lib/edm/edm.js +305 -226
- package/lib/edm/edmPreprocessor.js +509 -438
- package/lib/edm/edmUtils.js +31 -45
- package/lib/gen/Dictionary.json +98 -22
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +10 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20786 -22199
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +59 -51
- package/lib/json/to-csn.js +10 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +62 -39
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +348 -229
- package/lib/language/language.g4 +629 -653
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +46 -43
- package/lib/main.js +108 -79
- package/lib/model/csnRefs.js +34 -7
- package/lib/model/csnUtils.js +337 -332
- package/lib/model/enrichCsn.js +1 -0
- package/lib/model/revealInternalProperties.js +30 -10
- package/lib/model/sortViews.js +32 -31
- package/lib/modelCompare/compare.js +6 -6
- package/lib/optionProcessor.js +73 -46
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +1042 -882
- package/lib/render/toHdbcds.js +195 -245
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +225 -241
- package/lib/render/utils/common.js +145 -15
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +4 -3
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +4 -2
- package/lib/transform/db/expansion.js +22 -16
- package/lib/transform/db/flattening.js +109 -80
- package/lib/transform/db/transformExists.js +7 -7
- package/lib/transform/db/views.js +9 -6
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +62 -48
- package/lib/transform/forOdataNew.js +49 -50
- package/lib/transform/localized.js +31 -20
- package/lib/transform/odata/toFinalBaseType.js +16 -14
- package/lib/transform/odata/typesExposure.js +146 -198
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +67 -84
- package/lib/transform/translateAssocsToJoins.js +7 -3
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +16 -9
- package/lib/transform/universalCsn/universalCsnEnricher.js +60 -10
- package/lib/utils/file.js +3 -3
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/timetrace.js +20 -21
- package/package.json +35 -4
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
- package/lib/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -296
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
package/lib/api/options.js
CHANGED
|
@@ -24,7 +24,7 @@ const publicOptionsNewAPI = [
|
|
|
24
24
|
'sqlChangeMode',
|
|
25
25
|
'allowCsnDowngrade',
|
|
26
26
|
'joinfk',
|
|
27
|
-
'magicVars', // deprecated
|
|
27
|
+
'magicVars', // deprecated, not removed in v3 as we have specific error messages for it
|
|
28
28
|
'variableReplacements',
|
|
29
29
|
// ODATA
|
|
30
30
|
'odataVersion',
|
|
@@ -80,13 +80,12 @@ const overallOptions = publicOptionsNewAPI.concat(privateOptions);
|
|
|
80
80
|
function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
81
81
|
customValidators = {}, combinationValidators = [], moduleName = '') {
|
|
82
82
|
const options = Object.assign({}, defaults);
|
|
83
|
-
const inputOptionNames = Object.keys(input);
|
|
84
83
|
for (const name of overallOptions) {
|
|
85
84
|
// Ensure that arrays are not passed as a reference!
|
|
86
85
|
// This caused issues with the way messages are handled in processMessages
|
|
87
|
-
if (Array.isArray(input[name])
|
|
86
|
+
if (Array.isArray(input[name]))
|
|
88
87
|
options[name] = [ ...input[name] ];
|
|
89
|
-
else if (
|
|
88
|
+
else if (Object.hasOwnProperty.call(input, name))
|
|
90
89
|
options[name] = input[name];
|
|
91
90
|
}
|
|
92
91
|
|
|
@@ -108,47 +107,10 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
|
108
107
|
// Overwrite with the hardRequire options - like src: sql in to.sql()
|
|
109
108
|
Object.assign(options, hardRequire);
|
|
110
109
|
|
|
111
|
-
for (const optionName in options) {
|
|
112
|
-
const optionValue = options[optionName];
|
|
113
|
-
mapToOldNames(optionName, optionValue);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
110
|
// Convenience for $user -> $user.id replacement
|
|
117
111
|
if (options.variableReplacements && options.variableReplacements.$user && typeof options.variableReplacements.$user === 'string')
|
|
118
112
|
options.variableReplacements.$user = { id: options.variableReplacements.$user };
|
|
119
113
|
|
|
120
|
-
/**
|
|
121
|
-
* Map a new-style option to it's old format
|
|
122
|
-
*
|
|
123
|
-
* @param {string} optionName Name of the option to map
|
|
124
|
-
* @param {any} optionValue Value of the option to map
|
|
125
|
-
*/
|
|
126
|
-
function mapToOldNames(optionName, optionValue) {
|
|
127
|
-
// Keep all input options and add the "compatibility" options
|
|
128
|
-
switch (optionName) {
|
|
129
|
-
case 'beta':
|
|
130
|
-
options.betaMode = optionValue;
|
|
131
|
-
break;
|
|
132
|
-
case 'odataVersion':
|
|
133
|
-
options.version = optionValue;
|
|
134
|
-
break;
|
|
135
|
-
case 'sqlDialect':
|
|
136
|
-
options.dialect = optionValue;
|
|
137
|
-
break;
|
|
138
|
-
case 'sqlMapping':
|
|
139
|
-
options.names = optionValue;
|
|
140
|
-
break;
|
|
141
|
-
// No need to remap variableReplacements here - we use the new mechanism with that directly
|
|
142
|
-
case 'magicVars':
|
|
143
|
-
if (optionValue.user)
|
|
144
|
-
options.user = optionValue.user;
|
|
145
|
-
if (optionValue.locale)
|
|
146
|
-
options.locale = optionValue.locale;
|
|
147
|
-
break;
|
|
148
|
-
default: break;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
114
|
return options;
|
|
153
115
|
}
|
|
154
116
|
|
|
@@ -156,78 +118,45 @@ module.exports = {
|
|
|
156
118
|
to: {
|
|
157
119
|
cdl: options => translateOptions(options, undefined, undefined, undefined, undefined, 'to.cdl'),
|
|
158
120
|
sql: (options) => {
|
|
159
|
-
const hardOptions = { src: 'sql' };
|
|
121
|
+
const hardOptions = { src: 'sql', toSql: true, forHana: true };
|
|
160
122
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'plain' };
|
|
161
123
|
const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'sql-dialect-and-naming' ], 'to.sql');
|
|
162
124
|
|
|
163
|
-
|
|
164
|
-
result.toSql = Object.assign({}, processed);
|
|
165
|
-
|
|
166
|
-
return result;
|
|
125
|
+
return Object.assign({}, processed);
|
|
167
126
|
},
|
|
168
127
|
hdi: (options) => {
|
|
169
|
-
const hardOptions = { src: 'hdi' };
|
|
128
|
+
const hardOptions = { src: 'hdi', toSql: true, forHana: true };
|
|
170
129
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const result = Object.assign({}, processed);
|
|
174
|
-
result.toSql = Object.assign({}, processed);
|
|
175
|
-
|
|
176
|
-
return result;
|
|
130
|
+
return translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdi');
|
|
177
131
|
},
|
|
178
132
|
hdbcds: (options) => {
|
|
133
|
+
const hardOptions = { forHana: true };
|
|
179
134
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const result = Object.assign({}, processed);
|
|
183
|
-
result.forHana = Object.assign({}, processed);
|
|
184
|
-
|
|
185
|
-
return result;
|
|
135
|
+
return translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdbcds');
|
|
186
136
|
},
|
|
187
137
|
edm: (options) => {
|
|
188
|
-
const hardOptions = { json: true, combined: true };
|
|
138
|
+
const hardOptions = { json: true, combined: true, toOdata: true };
|
|
189
139
|
const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const result = Object.assign({}, processed);
|
|
193
|
-
result.toOdata = Object.assign({}, processed);
|
|
194
|
-
|
|
195
|
-
return result;
|
|
140
|
+
return translateOptions(options, defaultOptions, hardOptions, { odataVersion: generateStringValidator([ 'v4' ]) }, [ 'valid-structured' ], 'to.edm');
|
|
196
141
|
},
|
|
197
142
|
edmx: (options) => {
|
|
198
|
-
const hardOptions = { xml: true, combined: true };
|
|
143
|
+
const hardOptions = { xml: true, combined: true, toOdata: true };
|
|
199
144
|
const defaultOptions = {
|
|
200
145
|
odataVersion: 'v4', odataFormat: 'flat',
|
|
201
146
|
};
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const result = Object.assign({}, processed);
|
|
205
|
-
result.toOdata = Object.assign({}, processed);
|
|
206
|
-
|
|
207
|
-
return result;
|
|
147
|
+
return translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'to.edmx');
|
|
208
148
|
},
|
|
209
149
|
},
|
|
210
150
|
for: { // TODO: Rename version to oDataVersion
|
|
211
|
-
|
|
212
151
|
odata: (options) => {
|
|
152
|
+
const hardOptions = { toOdata: true };
|
|
213
153
|
const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const result = Object.assign({}, processed);
|
|
217
|
-
result.toOdata = Object.assign({}, processed);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return result;
|
|
154
|
+
return translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'for.odata');
|
|
221
155
|
},
|
|
222
156
|
hana: (options) => {
|
|
157
|
+
const hardOptions = { forHana: true };
|
|
223
158
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const result = Object.assign({}, processed);
|
|
227
|
-
result.forHana = Object.assign({}, processed);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return result;
|
|
159
|
+
return translateOptions(options, defaultOptions, hardOptions, undefined, undefined, 'for.hana');
|
|
231
160
|
},
|
|
232
161
|
},
|
|
233
162
|
};
|
package/lib/api/validate.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { makeMessageFunction } = require('../base/messages');
|
|
4
|
+
const { forEach } = require('../utils/objectUtils');
|
|
4
5
|
|
|
5
6
|
/* eslint-disable arrow-body-style */
|
|
6
7
|
const booleanValidator = {
|
|
@@ -64,13 +65,6 @@ const validators = {
|
|
|
64
65
|
return val === null ? val : `type ${ typeof val }`;
|
|
65
66
|
},
|
|
66
67
|
},
|
|
67
|
-
magicVars: {
|
|
68
|
-
validate: val => val !== null && typeof val === 'object' && !Array.isArray(val),
|
|
69
|
-
expected: () => 'type object',
|
|
70
|
-
found: (val) => {
|
|
71
|
-
return val === null ? val : `type ${ typeof val }`;
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
68
|
// TODO: Maybe do a deep validation of the whole object with leafs?
|
|
75
69
|
variableReplacements: {
|
|
76
70
|
validate: val => val !== null && typeof val === 'object' && !Array.isArray(val),
|
|
@@ -84,7 +78,7 @@ const validators = {
|
|
|
84
78
|
expected: () => 'type array',
|
|
85
79
|
found: val => `type ${ typeof val }`,
|
|
86
80
|
},
|
|
87
|
-
sqlDialect: generateStringValidator([ 'sqlite', 'hana', 'plain' ]),
|
|
81
|
+
sqlDialect: generateStringValidator([ 'sqlite', 'hana', 'plain', 'postgres' ]),
|
|
88
82
|
sqlMapping: generateStringValidator([ 'plain', 'quoted', 'hdbcds' ]),
|
|
89
83
|
odataVersion: generateStringValidator([ 'v2', 'v4' ]),
|
|
90
84
|
odataFormat: generateStringValidator([ 'flat', 'structured' ]),
|
|
@@ -130,16 +124,19 @@ const allCombinationValidators = {
|
|
|
130
124
|
'valid-structured': {
|
|
131
125
|
validate: options => options.odataVersion === 'v2' && options.odataFormat === 'structured',
|
|
132
126
|
severity: 'error',
|
|
127
|
+
getParameters: () => {},
|
|
133
128
|
getMessage: () => 'Structured OData is only supported with OData version v4',
|
|
134
129
|
},
|
|
135
130
|
'sql-dialect-and-naming': {
|
|
136
131
|
validate: options => options.sqlDialect && options.sqlMapping && ![ 'hana' ].includes(options.sqlDialect) && [ 'quoted', 'hdbcds' ].includes(options.sqlMapping),
|
|
137
132
|
severity: 'error',
|
|
138
|
-
|
|
133
|
+
getParameters: options => ({ name: options.sqlDialect, prop: options.sqlMapping }),
|
|
134
|
+
getMessage: () => 'sqlDialect $(NAME) can\'t be combined with sqlMapping $(PROP)',
|
|
139
135
|
},
|
|
140
136
|
'beta-no-test': {
|
|
141
137
|
validate: options => options.beta && !options.testMode,
|
|
142
138
|
severity: 'warning',
|
|
139
|
+
getParameters: () => {},
|
|
143
140
|
getMessage: () => 'Option "beta" was used. This option should not be used in productive scenarios!',
|
|
144
141
|
},
|
|
145
142
|
};
|
|
@@ -159,16 +156,15 @@ function validate(options, moduleName, customValidators = {}, combinationValidat
|
|
|
159
156
|
// TODO: issuing messages in this function looks very strange...
|
|
160
157
|
{
|
|
161
158
|
const messageCollector = { messages: [] };
|
|
162
|
-
const { error,
|
|
159
|
+
const { error, throwWithAnyError } = makeMessageFunction(null, messageCollector, moduleName);
|
|
163
160
|
|
|
164
|
-
|
|
165
|
-
const optionValue = options[optionName];
|
|
161
|
+
forEach(options, (optionName, optionValue) => {
|
|
166
162
|
const validator = customValidators[optionName] || validators[optionName] || booleanValidator;
|
|
167
163
|
|
|
168
164
|
if (!validator.validate(optionValue))
|
|
169
165
|
error('invalid-option', null, {}, `Expected option "${ optionName }" to have "${ validator.expected(optionValue) }". Found: "${ validator.found(optionValue) }"`);
|
|
170
|
-
}
|
|
171
|
-
|
|
166
|
+
});
|
|
167
|
+
throwWithAnyError();
|
|
172
168
|
}
|
|
173
169
|
|
|
174
170
|
const message = makeMessageFunction(null, options, moduleName);
|
|
@@ -176,10 +172,10 @@ function validate(options, moduleName, customValidators = {}, combinationValidat
|
|
|
176
172
|
for (const combinationValidatorName of combinationValidators.concat([ 'beta-no-test' ])) {
|
|
177
173
|
const combinationValidator = allCombinationValidators[combinationValidatorName];
|
|
178
174
|
if (combinationValidator.validate(options))
|
|
179
|
-
message[combinationValidator.severity]('invalid-option-combination', null,
|
|
175
|
+
message[combinationValidator.severity]('invalid-option-combination', null, combinationValidator.getParameters(options), combinationValidator.getMessage(options));
|
|
180
176
|
}
|
|
181
177
|
|
|
182
|
-
message.
|
|
178
|
+
message.throwWithAnyError();
|
|
183
179
|
}
|
|
184
180
|
/* eslint-enable jsdoc/no-undefined-types */
|
|
185
181
|
|