@sap/cds-dk 10.0.3 → 10.0.5
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 +28 -0
- package/bin/debug.js +6 -2
- package/bin/up.js +1 -1
- package/bin/watch.js +1 -0
- package/lib/build/plugins/helm/files/templates/_deployment_helpers.tpl +2 -0
- package/lib/build/plugins/nodejs/index.js +6 -3
- package/lib/build/util.js +1 -1
- package/lib/init/template/ams/files/containerize.yaml.hbs +1 -0
- package/lib/init/template/approuter/files/values.yaml.hbs +9 -1
- package/lib/init/template/data/as-csv.js +4 -2
- package/lib/init/template/data/as-json.js +4 -1
- package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +6 -6
- package/lib/init/template/ias/files/values.yaml.hbs +4 -4
- package/lib/init/template/portal/files/values.yaml.hbs +12 -0
- package/lib/init/template/sample/files/app/browse/fiori-service.cds +2 -0
- package/lib/init/template/typer/files/xsconfig.json +1 -1
- package/lib/init/template/typescript/files/package.json +1 -1
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/watch/esm-resolve-registration.js +27 -0
- package/lib/watch/vite-watch.js +1 -1
- package/node_modules/@cap-js/db-service/CHANGELOG.md +768 -0
- package/node_modules/@cap-js/db-service/LICENSE +201 -0
- package/node_modules/@cap-js/db-service/README.md +26 -0
- package/node_modules/@cap-js/db-service/index.js +19 -0
- package/node_modules/@cap-js/db-service/lib/InsertResults.js +122 -0
- package/node_modules/@cap-js/db-service/lib/SQLService.js +581 -0
- package/node_modules/@cap-js/db-service/lib/common/DatabaseService.js +179 -0
- package/node_modules/@cap-js/db-service/lib/common/factory.d.ts +5 -0
- package/node_modules/@cap-js/db-service/lib/common/generic-pool.js +310 -0
- package/node_modules/@cap-js/db-service/lib/common/session-context.js +46 -0
- package/node_modules/@cap-js/db-service/lib/converters.d.ts +24 -0
- package/node_modules/@cap-js/db-service/lib/cql-functions.js +464 -0
- package/node_modules/@cap-js/db-service/lib/cqn2pql.js +116 -0
- package/node_modules/@cap-js/db-service/lib/cqn2sql.js +1612 -0
- package/node_modules/@cap-js/db-service/lib/cqn4sql.js +2895 -0
- package/node_modules/@cap-js/db-service/lib/deep-queries.js +290 -0
- package/node_modules/@cap-js/db-service/lib/fill-in-keys.js +75 -0
- package/node_modules/@cap-js/db-service/lib/infer/cqn.d.ts +42 -0
- package/node_modules/@cap-js/db-service/lib/infer/index.js +1290 -0
- package/node_modules/@cap-js/db-service/lib/infer/join-tree.js +278 -0
- package/node_modules/@cap-js/db-service/lib/infer/pseudos.js +24 -0
- package/node_modules/@cap-js/db-service/lib/search.js +220 -0
- package/node_modules/@cap-js/db-service/lib/utils.js +177 -0
- package/node_modules/@cap-js/db-service/package.json +36 -0
- package/node_modules/@cap-js/sqlite/CHANGELOG.md +404 -0
- package/node_modules/@cap-js/sqlite/LICENSE +201 -0
- package/node_modules/@cap-js/sqlite/README.md +34 -0
- package/node_modules/@cap-js/sqlite/cds-plugin.js +0 -0
- package/node_modules/@cap-js/sqlite/index.js +2 -0
- package/node_modules/@cap-js/sqlite/lib/SQLiteService.js +324 -0
- package/node_modules/@cap-js/sqlite/lib/cql-functions.js +160 -0
- package/node_modules/@cap-js/sqlite/lib/node-sqlite.js +36 -0
- package/node_modules/@cap-js/sqlite/lib/session.json +3 -0
- package/node_modules/@cap-js/sqlite/lib/sql.js.js +99 -0
- package/node_modules/@cap-js/sqlite/package.json +68 -0
- package/node_modules/@sap/cds-compiler/CHANGELOG.md +14 -0
- package/node_modules/@sap/cds-compiler/bin/cdsse.js +1 -1
- package/node_modules/@sap/cds-compiler/bin/cdsv2m.js +1 -1
- package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +20 -13
- package/node_modules/@sap/cds-compiler/lib/base/builtins.js +4 -1
- package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +15 -2
- package/node_modules/@sap/cds-compiler/lib/checks/defaultValues.js +0 -1
- package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +6 -5
- package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +27 -6
- package/node_modules/@sap/cds-compiler/lib/edm/annotations/edmJson.js +5 -0
- package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +5 -4
- package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +14 -3
- package/node_modules/@sap/cds-compiler/lib/tool-lib/enrichCsn.js +1 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/cdsPersistence.js +3 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/views.js +2 -2
- package/node_modules/@sap/cds-compiler/lib/transform/transformUtils.js +1 -2
- package/node_modules/@sap/cds-compiler/package.json +1 -1
- package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/node_modules/ws/lib/receiver.js +15 -32
- package/node_modules/ws/lib/websocket-server.js +4 -4
- package/node_modules/ws/lib/websocket.js +4 -4
- package/node_modules/ws/package.json +5 -1
- package/package.json +5 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cap-js/sqlite",
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "CDS database service for SQLite",
|
|
5
|
+
"homepage": "https://github.com/cap-js/cds-dbs/tree/main/sqlite#cds-database-service-for-sqlite",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/cap-js/cds-dbs.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/cap-js/cds-dbs/issues"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"CAP",
|
|
15
|
+
"CDS",
|
|
16
|
+
"SQLite"
|
|
17
|
+
],
|
|
18
|
+
"author": "SAP SE (https://www.sap.com)",
|
|
19
|
+
"main": "index.js",
|
|
20
|
+
"files": [
|
|
21
|
+
"cds-plugin.js",
|
|
22
|
+
"lib",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "cds-test"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@cap-js/db-service": "^3.0.1"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@sap/cds": "^10",
|
|
33
|
+
"sql.js": "^1.13.0",
|
|
34
|
+
"better-sqlite3": "^12.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"sql.js": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"better-sqlite3": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"cds": {
|
|
45
|
+
"requires": {
|
|
46
|
+
"kinds": {
|
|
47
|
+
"sql": {
|
|
48
|
+
"[development]": {
|
|
49
|
+
"kind": "sqlite",
|
|
50
|
+
"credentials": {
|
|
51
|
+
"url": ":memory:"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"sqlite": {
|
|
56
|
+
"impl": "@cap-js/sqlite",
|
|
57
|
+
"pool": {
|
|
58
|
+
"evictionRunIntervalMillis": 0,
|
|
59
|
+
"min": 1,
|
|
60
|
+
"max": 1
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"db": "sql"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"license": "Apache-2.0"
|
|
68
|
+
}
|
|
@@ -15,6 +15,20 @@ might use a deprecated flag only for a limited period of time.
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
## Version 7.0.2 - 2026-07-14
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- **compiler:**
|
|
23
|
+
+ Avoid dump for a new association in a projection with backlink comparison while reporting a missing backlink target element.
|
|
24
|
+
+ Soften incompatibility concerning backlink comparisons: missing target elements which are referred to in the foreign keys or ON-condition of the backlink
|
|
25
|
+
association now only lead to a warning.
|
|
26
|
+
+ Soften incompatibility concerning structure values for annotations: a structure property like `list` won't be rejected; we avoid an ambiguity with an
|
|
27
|
+
_expression_ `(1, 2, 3)` by putting `'=': true` next to `list: …` in the CSN, like in compiler v6. A `xpr` expression is rendered without a sibling `=`,
|
|
28
|
+
though.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
18
32
|
## Version 7.0.1 - 2026-06-18
|
|
19
33
|
|
|
20
34
|
### ⚠ BREAKING CHANGES
|
|
@@ -201,7 +201,7 @@ function offset( buf, alsoSuffix ) { // for line and column
|
|
|
201
201
|
return false;
|
|
202
202
|
}
|
|
203
203
|
let cursor = pos + column - 1;
|
|
204
|
-
// eslint-disable-next-line sonarjs/
|
|
204
|
+
// eslint-disable-next-line sonarjs/super-linear-regex
|
|
205
205
|
const prefix = /[a-z_0-9$]*$/i.exec( buf.substring( pos, cursor ) ).index + pos;
|
|
206
206
|
const col = column + prefix - cursor;
|
|
207
207
|
if (alsoSuffix)
|
|
@@ -39,7 +39,7 @@ function ria() {
|
|
|
39
39
|
// 'Choose via $(ANNO) one of $(SORTED_ARTS) as redirection target for $(TARGET) in … $(ART) otherwise'
|
|
40
40
|
// NOTE: regex match on message text not for productive code!
|
|
41
41
|
for (const msgObj of msgs) {
|
|
42
|
-
// eslint-disable-next-line sonarjs/
|
|
42
|
+
// eslint-disable-next-line sonarjs/super-linear-regex
|
|
43
43
|
const matches = msgObj.message.match( /["“][^"”]+["”]/ug );
|
|
44
44
|
matches.slice( 1, -2 ).forEach( (name) => {
|
|
45
45
|
annotates[name.slice( 1, -1 )] = true;
|
|
@@ -173,7 +173,7 @@ In cds-compiler v7, we make `name-deprecated-$self` a non-configurable error.
|
|
|
173
173
|
Before cds-compiler v7:
|
|
174
174
|
The CSN representation of an expression-like annotation value is an object with
|
|
175
175
|
properties `=` and one of `ref`, `xpr`, `val`, `func`, `SELECT`, `list`.
|
|
176
|
-
In `=` we capture the (space-normalized, comments removed) string representation of the expression,
|
|
176
|
+
In `=` we capture the (space-normalized, comments removed) string CDL representation of the expression,
|
|
177
177
|
the other one holds the parsed expression as a token stream.
|
|
178
178
|
|
|
179
179
|
When the annotation is propagated ...
|
|
@@ -222,25 +222,32 @@ Resulting CSN:
|
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
In cds-compiler v7:
|
|
225
|
-
* For anno-xpr that are a simple ref (simple: can be path, but no filter, no parameters)
|
|
226
|
-
|
|
225
|
+
* For anno-xpr that are a simple ref (simple: can be path, but no filter, no parameters)
|
|
226
|
+
in the compiler and runtime CSN:
|
|
227
|
+
- In `=`, render the `.`-concatenated `ref` items without CDL escaping
|
|
228
|
+
(like for unchecked references, but unlike compiler v6);
|
|
229
|
+
e.g. for a reference, written as `(![in])` in CDL, use `{ '=': 'in', ref: ['in'] }` in CSN.
|
|
227
230
|
- When rewriting is necessary, also adapt the `=`.
|
|
231
|
+
* For expression which are a simple enum symbols, with or without surrounding parentheses:
|
|
232
|
+
- Just render the `#`, omit the `=` property.
|
|
233
|
+
* For expressions which are represented in CSN by a simple `xpr`:
|
|
234
|
+
- Do not render a `=` property anymore, just render the `xpr`.
|
|
228
235
|
* For all other expressions:
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
- Use `=` property with value `true`, do not use the CDL source as value,
|
|
237
|
+
both in original and in propagated annotations.
|
|
238
|
+
|
|
239
|
+
With the removal of `=`, any object in a CSN with just a `xpr`
|
|
240
|
+
is regarded as an expression value. With that, a structure inside an array
|
|
241
|
+
with just a `xpr` property could not be represented without ambiguity.
|
|
242
|
+
|
|
243
|
+
Therefore, the parser in v7 reports an error for such invalid structure values:
|
|
237
244
|
```cds
|
|
238
245
|
@A_xpr: [(2*foo)]
|
|
239
246
|
@A_str: [{xpr: [{val: 2}, '*', {ref: ['foo']}]}]
|
|
240
247
|
entity E { foo : Integer; }
|
|
241
248
|
```
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
The compiler also reports an error for structures inside arrays containing a `=` property and
|
|
250
|
+
a primary expression property (`ref`, `xpr`, `list`, `val`, `#`, `func`, `SELECT` and `SET`).
|
|
244
251
|
|
|
245
252
|
### Default for structures
|
|
246
253
|
|
|
@@ -107,7 +107,10 @@ const exprProperties = [
|
|
|
107
107
|
* Return whether JSON object `val` is a representation for an annotation expression
|
|
108
108
|
*/
|
|
109
109
|
function isAnnotationExpression( val ) {
|
|
110
|
-
return val &&
|
|
110
|
+
return val && (val['=']
|
|
111
|
+
? primaryExprProperties.some( prop => val[prop] !== undefined )
|
|
112
|
+
: val.xpr !== undefined && Object.keys( val ).length === 1 || val['#'] !== undefined
|
|
113
|
+
);
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
module.exports = {
|
|
@@ -147,6 +147,8 @@ const centralMessages = {
|
|
|
147
147
|
'ref-invalid-source': { severity: 'Error' },
|
|
148
148
|
'ref-invalid-target': { severity: 'Error' },
|
|
149
149
|
'ref-invalid-backlink': { severity: 'Error', configurableFor: 'before_v8' },
|
|
150
|
+
'ref-missing-backlink-element': { severity: 'Warning', errorFor: [ 'v8' ] },
|
|
151
|
+
'ref-deprecated-backlink': { severity: 'Warning', errorFor: [ 'v8' ] },
|
|
150
152
|
'ref-missing-self-counterpart': { severity: 'Error', configurableFor: true },
|
|
151
153
|
'ref-sloppy-target': { severity: 'Error', configurableFor: 'deprecated_before_v8' },
|
|
152
154
|
|
|
@@ -546,8 +548,10 @@ const centralMessageTexts = {
|
|
|
546
548
|
colon: 'Use a $(NEWCODE), not a $(CODE) between the element names in a reference',
|
|
547
549
|
},
|
|
548
550
|
'syntax-invalid-anno-struct': {
|
|
549
|
-
std: '
|
|
550
|
-
|
|
551
|
+
std: 'Objects with properties $(PROP) and $(SIBLINGPROP) are reserved for expressions and can\'t be used as structures',
|
|
552
|
+
xpr: 'Objects with $(PROP) as only property are reserved for expressions and can\'t be used as structures',
|
|
553
|
+
'#': 'Objects with a property $(PROP) are reserved for enum values and can\'t be used as structures',
|
|
554
|
+
ref: 'The value of property $(PROP) in structures must be a non-empty string',
|
|
551
555
|
},
|
|
552
556
|
// 'syntax-ignoring-doc-comment' (Info)
|
|
553
557
|
'syntax-unexpected-reserved-word': '$(CODE) is a reserved word - write $(DELIMITED) instead if you want to use it as name',
|
|
@@ -917,6 +921,7 @@ const centralMessageTexts = {
|
|
|
917
921
|
'rewrite-undefined-key': {
|
|
918
922
|
std: 'Can\'t redirect association $(NAME), as redirection target $(TARGET) does not project element $(ID), which is required to match foreign key of $(NAME)',
|
|
919
923
|
backlink: 'Can\'t project association, as the current entity does not project element $(ID), which is required to match foreign key of the backlink association',
|
|
924
|
+
// TODO: delete text variant 'backlink' again
|
|
920
925
|
},
|
|
921
926
|
'type-unexpected-typeof': {
|
|
922
927
|
std: 'Unexpected $(KEYWORD) for the type reference here',
|
|
@@ -1180,6 +1185,14 @@ const centralMessageTexts = {
|
|
|
1180
1185
|
include: 'The open backlink target $(TARGET) of the aspect is unrelated to the current entity',
|
|
1181
1186
|
backlink: 'Can\'t use $(ART) as backlink association, because its ON-condition contains a backlink comparison',
|
|
1182
1187
|
},
|
|
1188
|
+
'ref-deprecated-backlink': {
|
|
1189
|
+
std: 'The target $(TARGET) of the backlink association is just distantly related to the current entity; do not use a comparison with $(ID)',
|
|
1190
|
+
inferred: 'The target $(TARGET) of the backlink association $(NAME) is just distantly related to the current entity; provide an ON-condition not using a comparison with $(ID)',
|
|
1191
|
+
},
|
|
1192
|
+
'ref-missing-backlink-element': {
|
|
1193
|
+
std: 'Element $(ID) must also be projected when projecting this association containing a backlink comparison',
|
|
1194
|
+
def: 'Element $(ID) must be projected when defining this association containing a backlink comparison',
|
|
1195
|
+
},
|
|
1183
1196
|
'extend-columns': {
|
|
1184
1197
|
std: 'Artifact $(ART) can\'t be extended with columns, only simple views/projections without JOINs and UNIONs can',
|
|
1185
1198
|
join: 'Artifact $(ART) can\'t be extended with columns, because it contains a JOIN',
|
|
@@ -23,7 +23,6 @@ function validateDefaultValues( member, memberName, prop, path ) {
|
|
|
23
23
|
// TODO: This check only counts the number of leading signs, not inbetween (e.g. 1 - - 1).
|
|
24
24
|
// The message also needs to be improved.
|
|
25
25
|
if (i > 1)
|
|
26
|
-
// eslint-disable-next-line cds-compiler/message-no-quotes
|
|
27
26
|
this.error(null, path, {}, 'Illegal number of unary \'+\'/\'-\' operators');
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -1229,7 +1229,8 @@ function resolve( model ) {
|
|
|
1229
1229
|
function checkBacklinkPartner( assoc ) {
|
|
1230
1230
|
checkBareDollarSelf( assoc );
|
|
1231
1231
|
// console.log('CBP:',assoc.kind,assoc._main?.name?.id,assoc.name.id,!!assoc.$backlink)
|
|
1232
|
-
const
|
|
1232
|
+
const origin = assoc.$backlink?._origin;
|
|
1233
|
+
const target = origin?.target?._artifact;
|
|
1233
1234
|
if (!target)
|
|
1234
1235
|
return;
|
|
1235
1236
|
const main = assoc._main;
|
|
@@ -1254,10 +1255,10 @@ function resolve( model ) {
|
|
|
1254
1255
|
// TODO: we should do the "simple projection ancestor" probably only if no
|
|
1255
1256
|
// include is involved in the redirection chain
|
|
1256
1257
|
if (redirectionChain( null, main, ancestor, true )) {
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
// eslint-disable-next-line @stylistic/
|
|
1260
|
-
'
|
|
1258
|
+
const msg = (assoc.on.$inferred ? 'inferred' : 'std');
|
|
1259
|
+
message( 'ref-deprecated-backlink', [ assoc.$backlink.location, assoc ],
|
|
1260
|
+
// eslint-disable-next-line @stylistic/object-curly-newline
|
|
1261
|
+
{ '#': msg, target, id: '$self', name: origin.name.id } );
|
|
1261
1262
|
return;
|
|
1262
1263
|
}
|
|
1263
1264
|
}
|
|
@@ -450,13 +450,24 @@ function tweakAssocs( model ) {
|
|
|
450
450
|
if (projectedKey.index > 0)
|
|
451
451
|
targetElement.path.splice(0, projectedKey.index);
|
|
452
452
|
}
|
|
453
|
+
else if (elem._outer?.$backlink === elem) {
|
|
454
|
+
const undef = targetElement.path[0];
|
|
455
|
+
setArtifactLink( undef, null );
|
|
456
|
+
setArtifactLink( targetElement, null );
|
|
457
|
+
const outer = elem._outer;
|
|
458
|
+
message( 'ref-missing-backlink-element',
|
|
459
|
+
[ (outer.value || outer.name).location, outer ],
|
|
460
|
+
{ '#': (outer.value ? 'std' : 'def'), id: undef.id } );
|
|
461
|
+
// TODO: more info if element was already missing in "intermediate" projection
|
|
462
|
+
// TODO: collect all missing elements?
|
|
463
|
+
}
|
|
453
464
|
else {
|
|
454
465
|
setArtifactLink( targetElement.path[0], null );
|
|
455
466
|
setArtifactLink( targetElement, null );
|
|
456
467
|
|
|
457
468
|
const culprit = !elem.target.$inferred && elem.target ||
|
|
458
|
-
|
|
459
|
-
|
|
469
|
+
elem.value?.path?.[elem.value.path.length - 1] ||
|
|
470
|
+
elem;
|
|
460
471
|
// TODO: probably better to collect the non-projected foreign keys
|
|
461
472
|
// and have one message for all
|
|
462
473
|
error( 'rewrite-undefined-key', [ weakLocation( culprit.location ), elem ], {
|
|
@@ -825,8 +836,16 @@ function tweakAssocs( model ) {
|
|
|
825
836
|
if (!item)
|
|
826
837
|
return; // just $self
|
|
827
838
|
// console.log('REB:',assoc.name?.id,expr.path.map(i=>i.id))
|
|
828
|
-
if (item.id === assoc.name.id
|
|
829
|
-
|
|
839
|
+
if (item.id === assoc.name.id &&
|
|
840
|
+
rewritePath( expr, item, assoc, assoc, null )) {
|
|
841
|
+
const undef = expr.path.find( i => !i._artifact );
|
|
842
|
+
const outer = assoc._outer;
|
|
843
|
+
message( 'ref-missing-backlink-element',
|
|
844
|
+
[ (outer.value || outer.name).location, outer ],
|
|
845
|
+
{ '#': (outer.value ? 'std' : 'def'), id: undef.id } );
|
|
846
|
+
// TODO: more info if element was already missing in "intermediate" projection
|
|
847
|
+
// TODO: collect all missing elements?
|
|
848
|
+
}
|
|
830
849
|
}
|
|
831
850
|
else if (assoc._main.query) { // from ON cond of mixin element in query
|
|
832
851
|
// here also $calc
|
|
@@ -877,7 +896,7 @@ function tweakAssocs( model ) {
|
|
|
877
896
|
element: 'This element is not originally referred to in the ON-condition of association $(MEMBER) of $(ART)',
|
|
878
897
|
} );
|
|
879
898
|
}
|
|
880
|
-
rewritePath( expr, item, assoc, elem, null );
|
|
899
|
+
rewritePath( expr, item, assoc, elem, null ); // TODO: really no error?
|
|
881
900
|
}
|
|
882
901
|
}
|
|
883
902
|
|
|
@@ -1044,6 +1063,8 @@ function tweakAssocs( model ) {
|
|
|
1044
1063
|
* Rewrite the reference `ref` with first elem/mixin ref item `item` for user
|
|
1045
1064
|
* `assoc` (the query element). `elem` is usually the first (or preferred)
|
|
1046
1065
|
* query element for item.
|
|
1066
|
+
*
|
|
1067
|
+
* If `location` is falsy, do not issue an error.
|
|
1047
1068
|
*/
|
|
1048
1069
|
function rewritePath( ref, item, assoc, elem, location ) {
|
|
1049
1070
|
const { path } = ref;
|
|
@@ -1092,7 +1113,7 @@ function tweakAssocs( model ) {
|
|
|
1092
1113
|
if (state && state !== true)
|
|
1093
1114
|
continue;
|
|
1094
1115
|
if (!state && !location)
|
|
1095
|
-
return true;
|
|
1116
|
+
return true; // no rewrite possible
|
|
1096
1117
|
break;
|
|
1097
1118
|
}
|
|
1098
1119
|
}
|
|
@@ -978,6 +978,11 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions, generi
|
|
|
978
978
|
return xpr;
|
|
979
979
|
}
|
|
980
980
|
|
|
981
|
+
// "'=': true" has no meaning as an OData operator here and must be removed
|
|
982
|
+
// before transform runs, otherwise transform['='] misinterprets it as $Eq.
|
|
983
|
+
if (xpr['='] === true)
|
|
984
|
+
delete xpr['='];
|
|
985
|
+
|
|
981
986
|
if (xpr.list)
|
|
982
987
|
xpr.list.forEach( preTransformExpression );
|
|
983
988
|
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
|
|
118
118
|
const { dictAdd } = require('../compiler/dictionaries');
|
|
119
119
|
const { quotedLiteralPatterns } = require('../compiler/builtins');
|
|
120
|
-
const { exprProperties,
|
|
120
|
+
const { exprProperties, isAnnotationExpression } = require('../base/builtins');
|
|
121
121
|
const { CompilerAssertion } = require('../base/error');
|
|
122
122
|
const { Location } = require('../base/location');
|
|
123
123
|
const { XsnSource } = require('../compiler/xsn-model');
|
|
@@ -1490,10 +1490,10 @@ function annoValue( val, spec ) {
|
|
|
1490
1490
|
}
|
|
1491
1491
|
return retval;
|
|
1492
1492
|
}
|
|
1493
|
-
else if (
|
|
1493
|
+
else if (isAnnotationExpression( val )) {
|
|
1494
1494
|
const s = schema['@'].schema['-expr'];
|
|
1495
1495
|
const r = object( val, s );
|
|
1496
|
-
r.$tokenTexts = true;
|
|
1496
|
+
r.$tokenTexts = true;
|
|
1497
1497
|
return r;
|
|
1498
1498
|
}
|
|
1499
1499
|
else if (val['...'] !== undefined && Object.keys( val ).length === 1) {
|
|
@@ -1149,10 +1149,11 @@ function annoValue( node ) {
|
|
|
1149
1149
|
if (!node.$tokenTexts)
|
|
1150
1150
|
return value( node );
|
|
1151
1151
|
const csn = expression( node ); // expressions in annotation values
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1152
|
+
if (!csn || csn['#'] || csn.xpr && Object.keys( csn ).length === 1)
|
|
1153
|
+
return csn; // '#' and 'xpr' without sibling '='
|
|
1154
|
+
const asTrue = !csn?.ref || gensrcFlavor || universalCsn ||
|
|
1155
|
+
csn.cast || csn.param || csn.ref.some( id => typeof id !== 'string' );
|
|
1156
|
+
return Object.assign({ '=': !!asTrue || csn.ref.join( '.' ) }, csn );
|
|
1156
1157
|
}
|
|
1157
1158
|
|
|
1158
1159
|
function value( node ) {
|
|
@@ -1190,15 +1190,26 @@ class AstBuildingParser extends BaseParser {
|
|
|
1190
1190
|
}
|
|
1191
1191
|
|
|
1192
1192
|
checkStructProps( dict ) {
|
|
1193
|
+
// see also isAnnotationExpression()
|
|
1194
|
+
if (!dict['=']) {
|
|
1195
|
+
const prop = dict['#'] && '#' ||
|
|
1196
|
+
dict.xpr && Object.keys( dict ).length === 1 && 'xpr';
|
|
1197
|
+
if (!prop)
|
|
1198
|
+
return;
|
|
1199
|
+
this.error( 'syntax-invalid-anno-struct', dict[prop].name.location,
|
|
1200
|
+
{ '#': prop, prop } );
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1193
1203
|
const prop = primaryExprProperties.find( p => dict[p] !== undefined );
|
|
1194
1204
|
if (prop) {
|
|
1195
1205
|
this.error( 'syntax-invalid-anno-struct', dict[prop].name.location,
|
|
1196
|
-
{ '#': 'std', prop } );
|
|
1206
|
+
{ '#': 'std', prop, siblingprop: '=' } );
|
|
1197
1207
|
}
|
|
1198
|
-
else if (dict['=']
|
|
1208
|
+
else if (dict['='].literal !== 'string' || !dict['='].val) {
|
|
1199
1209
|
this.error( 'syntax-invalid-anno-struct', dict['='].location,
|
|
1200
1210
|
{ '#': 'ref', prop: '=' } );
|
|
1201
1211
|
}
|
|
1212
|
+
// TODO: also check '...' ?
|
|
1202
1213
|
}
|
|
1203
1214
|
|
|
1204
1215
|
// TODO: remove the check from the parser; move it to shared.js
|
|
@@ -1635,7 +1646,7 @@ function addOneForDefinition( count, ext ) {
|
|
|
1635
1646
|
|
|
1636
1647
|
// Significant digits (before exponent) without leading and trailing zeros
|
|
1637
1648
|
function relevantDigits( val ) {
|
|
1638
|
-
// eslint-disable-next-line sonarjs/
|
|
1649
|
+
// eslint-disable-next-line sonarjs/super-linear-regex
|
|
1639
1650
|
val = val.replace( /e.+$/i, '' ); // this regex has no newlines -> is not slow
|
|
1640
1651
|
|
|
1641
1652
|
const init = /^[-+0.]+/g; // global flag to have lastIndex
|
|
@@ -143,7 +143,7 @@ function enrichCsn( csn, options = {} ) {
|
|
|
143
143
|
}
|
|
144
144
|
else {
|
|
145
145
|
const record = !isAnnotationExpression( obj ) && assignment;
|
|
146
|
-
// is record without primary expression property
|
|
146
|
+
// is record without primary expression property and usually '='
|
|
147
147
|
for (const name of Object.getOwnPropertyNames( obj ) ) {
|
|
148
148
|
const trans = record || transformers[name] || transformers[name.charAt(0)] || standard;
|
|
149
149
|
trans( obj, name, obj[name] );
|
|
@@ -51,11 +51,12 @@ function getAssocToSkippedIgnorer( csn, options, messageFunctions, csnUtils ) {
|
|
|
51
51
|
*
|
|
52
52
|
* @param {CSN.Artifact} artifact
|
|
53
53
|
* @param {string} artifactName
|
|
54
|
+
* @param {string} _prop
|
|
55
|
+
* @param {CSN.Path} _path
|
|
54
56
|
*/
|
|
55
57
|
function ignoreAssociationToSkippedTarget( artifact, artifactName, _prop, _path ) {
|
|
56
|
-
if (isPersistedOnDatabase(artifact))
|
|
58
|
+
if (isPersistedOnDatabase(artifact))
|
|
57
59
|
forEachMemberRecursively(artifact, ignore, [ 'definitions', artifactName ]);
|
|
58
|
-
}
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/**
|
|
@@ -130,6 +130,7 @@ function getViewTransformer( csn, options, _messageFunctions ) {
|
|
|
130
130
|
* @param {CSN.Element} elem
|
|
131
131
|
* @param {string} elemName
|
|
132
132
|
* @param {CSN.Path} elementsPath Path pointing to elements
|
|
133
|
+
* @param {CSN.Path} _queryPath
|
|
133
134
|
*/
|
|
134
135
|
function handleAssociationElement( query, elements, columnMap, publishedMixins, elem, elemName, elementsPath, _queryPath ) {
|
|
135
136
|
const isNotMixinByItself = checkIsNotMixinByItself(query, columnMap, elemName);
|
|
@@ -391,9 +392,8 @@ function getColumnMap( query, csnUtils ) {
|
|
|
391
392
|
function ensureColumnNames( query, csnUtils, _options ) {
|
|
392
393
|
const select = query.SELECT || query.projection;
|
|
393
394
|
for (const col of select?.columns || []) {
|
|
394
|
-
if (col !== '*' && !columnAlias(col))
|
|
395
|
+
if (col !== '*' && !columnAlias(col))
|
|
395
396
|
setProp(col, 'as', csnUtils.getColumnName(col));
|
|
396
|
-
}
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
|
|
@@ -218,9 +218,8 @@ function getTransformers(model, options, msgFunctions, pathDelimiter = '_') {
|
|
|
218
218
|
if (flattenedNames.length === 1) {
|
|
219
219
|
// Single element: propagate default if leaf doesn't have one
|
|
220
220
|
const singleElem = result[flattenedNames[0]];
|
|
221
|
-
if (singleElem.default?.val === undefined)
|
|
221
|
+
if (singleElem.default?.val === undefined)
|
|
222
222
|
singleElem.default = elem.default; // Copy entire default object {val, location}
|
|
223
|
-
}
|
|
224
223
|
}
|
|
225
224
|
else if (flattenedNames.length > 1) {
|
|
226
225
|
// Multi-element structure: warn that default is ignored
|
|
@@ -31,7 +31,9 @@ function Utf32Encoder (options, codec) {
|
|
|
31
31
|
|
|
32
32
|
Utf32Encoder.prototype.write = function (str) {
|
|
33
33
|
var src = Buffer.from(str, "ucs2")
|
|
34
|
-
|
|
34
|
+
// src.length * 2 covers this chunk's code units (4 bytes each); the extra 4 bytes leave room for a
|
|
35
|
+
// high surrogate held over from a previous chunk, which is flushed ahead of this chunk's units.
|
|
36
|
+
var dst = Buffer.alloc(src.length * 2 + 4)
|
|
35
37
|
var write32 = this.isLE ? dst.writeUInt32LE : dst.writeUInt32BE
|
|
36
38
|
var offset = 0
|
|
37
39
|
|
|
@@ -113,9 +115,9 @@ Utf32Decoder.prototype.write = function (src) {
|
|
|
113
115
|
// NOTE: codepoint is a signed int32 and can be negative.
|
|
114
116
|
// NOTE: We copied this block from below to help V8 optimize it (it works with array, not buffer).
|
|
115
117
|
if (isLE) {
|
|
116
|
-
codepoint = overflow[
|
|
118
|
+
codepoint = overflow[0] | (overflow[1] << 8) | (overflow[2] << 16) | (overflow[3] << 24)
|
|
117
119
|
} else {
|
|
118
|
-
codepoint = overflow[
|
|
120
|
+
codepoint = overflow[3] | (overflow[2] << 8) | (overflow[1] << 16) | (overflow[0] << 24)
|
|
119
121
|
}
|
|
120
122
|
overflow.length = 0
|
|
121
123
|
|
|
@@ -169,7 +171,12 @@ function _writeCodepoint (dst, offset, codepoint, badChar) {
|
|
|
169
171
|
};
|
|
170
172
|
|
|
171
173
|
Utf32Decoder.prototype.end = function () {
|
|
174
|
+
if (this.overflow.length === 0) { return }
|
|
175
|
+
|
|
176
|
+
// A leftover, incomplete 4-byte code unit at the end of the input is ill-formed. Substitute a
|
|
177
|
+
// single U+FFFD (Unicode Standard conformance clause C10) instead of silently dropping the bytes.
|
|
172
178
|
this.overflow.length = 0
|
|
179
|
+
return String.fromCharCode(this.badChar)
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
// == UTF-32 Auto codec =============================================================
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iconv-lite",
|
|
3
3
|
"description": "Convert character encodings in pure javascript.",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"iconv",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"stream": false
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@arethetypeswrong/cli": "^0.
|
|
49
|
+
"@arethetypeswrong/cli": "^0.18.4",
|
|
50
50
|
"@stylistic/eslint-plugin": "^5.1.0",
|
|
51
51
|
"@stylistic/eslint-plugin-js": "^4.1.0",
|
|
52
52
|
"@types/node": "^24.0.12",
|
|
@@ -77,6 +77,7 @@ class Receiver extends Writable {
|
|
|
77
77
|
|
|
78
78
|
this._totalPayloadLength = 0;
|
|
79
79
|
this._messageLength = 0;
|
|
80
|
+
this._numFragments = 0;
|
|
80
81
|
this._fragments = [];
|
|
81
82
|
|
|
82
83
|
this._errored = false;
|
|
@@ -500,6 +501,19 @@ class Receiver extends Writable {
|
|
|
500
501
|
return;
|
|
501
502
|
}
|
|
502
503
|
|
|
504
|
+
if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
|
|
505
|
+
const error = this.createError(
|
|
506
|
+
RangeError,
|
|
507
|
+
'Too many message fragments',
|
|
508
|
+
false,
|
|
509
|
+
1008,
|
|
510
|
+
'WS_ERR_TOO_MANY_BUFFERED_PARTS'
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
cb(error);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
|
|
503
517
|
if (this._compressed) {
|
|
504
518
|
this._state = INFLATING;
|
|
505
519
|
this.decompress(data, cb);
|
|
@@ -507,22 +521,6 @@ class Receiver extends Writable {
|
|
|
507
521
|
}
|
|
508
522
|
|
|
509
523
|
if (data.length) {
|
|
510
|
-
if (
|
|
511
|
-
this._maxFragments > 0 &&
|
|
512
|
-
this._fragments.length >= this._maxFragments
|
|
513
|
-
) {
|
|
514
|
-
const error = this.createError(
|
|
515
|
-
RangeError,
|
|
516
|
-
'Too many message fragments',
|
|
517
|
-
false,
|
|
518
|
-
1008,
|
|
519
|
-
'WS_ERR_TOO_MANY_BUFFERED_PARTS'
|
|
520
|
-
);
|
|
521
|
-
|
|
522
|
-
cb(error);
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
524
|
//
|
|
527
525
|
// This message is not compressed so its length is the sum of the payload
|
|
528
526
|
// length of all fragments.
|
|
@@ -562,22 +560,6 @@ class Receiver extends Writable {
|
|
|
562
560
|
return;
|
|
563
561
|
}
|
|
564
562
|
|
|
565
|
-
if (
|
|
566
|
-
this._maxFragments > 0 &&
|
|
567
|
-
this._fragments.length >= this._maxFragments
|
|
568
|
-
) {
|
|
569
|
-
const error = this.createError(
|
|
570
|
-
RangeError,
|
|
571
|
-
'Too many message fragments',
|
|
572
|
-
false,
|
|
573
|
-
1008,
|
|
574
|
-
'WS_ERR_TOO_MANY_BUFFERED_PARTS'
|
|
575
|
-
);
|
|
576
|
-
|
|
577
|
-
cb(error);
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
563
|
this._fragments.push(buf);
|
|
582
564
|
}
|
|
583
565
|
|
|
@@ -604,6 +586,7 @@ class Receiver extends Writable {
|
|
|
604
586
|
this._totalPayloadLength = 0;
|
|
605
587
|
this._messageLength = 0;
|
|
606
588
|
this._fragmented = 0;
|
|
589
|
+
this._numFragments = 0;
|
|
607
590
|
this._fragments = [];
|
|
608
591
|
|
|
609
592
|
if (this._opcode === 2) {
|