@sap/cds 6.0.4 → 6.1.2
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 +180 -18
- package/apis/cds.d.ts +11 -7
- package/apis/log.d.ts +124 -0
- package/apis/ql.d.ts +72 -15
- package/apis/services.d.ts +13 -2
- package/bin/build/buildTaskHandler.js +5 -2
- package/bin/build/constants.js +4 -1
- package/bin/build/provider/buildTaskHandlerEdmx.js +11 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +14 -34
- package/bin/build/provider/buildTaskHandlerInternal.js +56 -4
- package/bin/build/provider/buildTaskProviderInternal.js +22 -14
- package/bin/build/provider/hana/index.js +12 -9
- package/bin/build/provider/java/index.js +18 -8
- package/bin/build/provider/mtx/index.js +7 -4
- package/bin/build/provider/mtx/resourcesTarBuilder.js +60 -35
- package/bin/build/provider/mtx-extension/index.js +57 -0
- package/bin/build/provider/mtx-sidecar/index.js +46 -18
- package/bin/build/provider/nodejs/index.js +34 -13
- package/bin/deploy/to-hana/cfUtil.js +7 -2
- package/bin/deploy/to-hana/hana.js +20 -25
- package/bin/deploy/to-hana/hdiDeployUtil.js +13 -2
- package/bin/serve.js +7 -4
- package/lib/compile/{index.js → cds-compile.js} +0 -0
- package/lib/compile/extend.js +15 -5
- package/lib/compile/minify.js +1 -15
- package/lib/compile/parse.js +1 -1
- package/lib/compile/resolve.js +2 -2
- package/lib/compile/to/srvinfo.js +6 -4
- package/lib/{deploy.js → dbs/cds-deploy.js} +9 -8
- package/lib/env/{index.js → cds-env.js} +1 -17
- package/lib/env/{requires.js → cds-requires.js} +24 -3
- package/lib/env/defaults.js +7 -1
- package/lib/env/schemas/cds-package.json +11 -0
- package/lib/env/schemas/cds-rc.json +614 -0
- package/lib/index.js +19 -16
- package/lib/log/{errors.js → cds-error.js} +1 -1
- package/lib/log/{index.js → cds-log.js} +0 -0
- package/lib/log/format/kibana.js +19 -1
- package/lib/ql/Query.js +9 -3
- package/lib/ql/SELECT.js +2 -2
- package/lib/ql/UPDATE.js +2 -2
- package/lib/ql/{index.js → cds-ql.js} +4 -10
- package/lib/req/context.js +49 -17
- package/lib/req/locale.js +5 -1
- package/lib/{serve → srv}/adapters.js +23 -19
- package/lib/{connect → srv}/bindings.js +0 -0
- package/lib/{connect/index.js → srv/cds-connect.js} +1 -1
- package/lib/{serve/index.js → srv/cds-serve.js} +0 -0
- package/lib/{serve → srv}/factory.js +1 -1
- package/lib/{serve/Service-api.js → srv/srv-api.js} +22 -6
- package/lib/{serve/Service-dispatch.js → srv/srv-dispatch.js} +13 -8
- package/lib/{serve/Service-handlers.js → srv/srv-handlers.js} +10 -0
- package/lib/{serve/Service-methods.js → srv/srv-methods.js} +10 -8
- package/lib/srv/srv-models.js +207 -0
- package/lib/{serve/Transaction.js → srv/srv-tx.js} +57 -40
- package/lib/utils/{tests.js → cds-test.js} +2 -2
- package/lib/utils/cds-utils.js +146 -0
- package/lib/utils/index.js +2 -145
- package/lib/utils/jest.js +43 -0
- package/lib/utils/resources/index.js +15 -25
- package/lib/utils/resources/tar.js +18 -41
- package/libx/_runtime/auth/index.js +14 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +7 -19
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +6 -19
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +3 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +0 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/deserializer/DeserializerFactory.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +38 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -3
- package/libx/_runtime/cds-services/services/utils/differ.js +4 -0
- package/libx/_runtime/cds-services/util/errors.js +1 -29
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/perf/index.js +10 -15
- package/libx/_runtime/common/utils/binary.js +3 -4
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +0 -1
- package/libx/_runtime/common/utils/entityFromCqn.js +8 -5
- package/libx/_runtime/common/utils/keys.js +14 -6
- package/libx/_runtime/common/utils/resolveView.js +1 -1
- package/libx/_runtime/common/utils/template.js +1 -1
- package/libx/_runtime/db/Service.js +2 -14
- package/libx/_runtime/db/expand/expandCQNToJoin.js +28 -25
- package/libx/_runtime/db/expand/rawToExpanded.js +7 -6
- package/libx/_runtime/db/generic/input.js +8 -1
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +37 -18
- package/libx/_runtime/extensibility/activate.js +47 -47
- package/libx/_runtime/extensibility/add.js +22 -13
- package/libx/_runtime/extensibility/addExtension.js +17 -13
- package/libx/_runtime/extensibility/defaults.js +25 -30
- package/libx/_runtime/extensibility/handler/transformREAD.js +20 -18
- package/libx/_runtime/extensibility/linter/allowlist_checker.js +373 -0
- package/libx/_runtime/extensibility/linter/annotations_checker.js +113 -0
- package/libx/_runtime/extensibility/linter/checker_base.js +20 -0
- package/libx/_runtime/extensibility/linter/namespace_checker.js +180 -0
- package/libx/_runtime/extensibility/linter.js +32 -0
- package/libx/_runtime/extensibility/push.js +77 -20
- package/libx/_runtime/extensibility/service.js +29 -12
- package/libx/_runtime/extensibility/token.js +57 -0
- package/libx/_runtime/extensibility/utils.js +8 -6
- package/libx/_runtime/extensibility/validation.js +6 -9
- package/libx/_runtime/fiori/generic/new.js +0 -11
- package/libx/_runtime/fiori/utils/where.js +1 -1
- package/libx/_runtime/hana/Service.js +0 -1
- package/libx/_runtime/hana/conversion.js +12 -1
- package/libx/_runtime/hana/customBuilder/CustomFunctionBuilder.js +4 -3
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -0
- package/libx/_runtime/hana/pool.js +6 -10
- package/libx/_runtime/hana/search2Contains.js +0 -5
- package/libx/_runtime/hana/search2cqn4sql.js +1 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +1 -2
- package/libx/_runtime/messaging/outbox/utils.js +1 -1
- package/libx/_runtime/messaging/service.js +11 -6
- package/libx/_runtime/remote/utils/data.js +5 -0
- package/libx/_runtime/sqlite/Service.js +7 -6
- package/libx/_runtime/sqlite/execute.js +41 -28
- package/libx/odata/afterburner.js +79 -2
- package/libx/odata/cqn2odata.js +15 -9
- package/libx/odata/grammar.pegjs +157 -76
- package/libx/odata/index.js +9 -3
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +39 -5
- package/libx/rest/RestAdapter.js +3 -7
- package/libx/rest/middleware/delete.js +4 -5
- package/libx/rest/middleware/parse.js +3 -2
- package/package.json +3 -3
- package/server.js +1 -1
- package/srv/extensibility-service.cds +6 -3
- package/srv/model-provider.cds +3 -1
- package/srv/model-provider.js +86 -106
- package/srv/mtx.js +7 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +0 -240
package/libx/odata/grammar.pegjs
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
//
|
|
28
28
|
// ---------- JavaScript Helpers -------------
|
|
29
29
|
{
|
|
30
|
+
|
|
30
31
|
const $ = Object.assign
|
|
31
32
|
const { strict, minimal } = options
|
|
32
33
|
const stack = []
|
|
@@ -243,7 +244,7 @@
|
|
|
243
244
|
|
|
244
245
|
ODataRelativeURI // Note: case-sensitive!
|
|
245
246
|
= '/'? (p:path { SELECT = p })
|
|
246
|
-
( o"?"o QueryOption ( o'&'o QueryOption )*
|
|
247
|
+
( o"?"o (QueryOption ( o'&'o QueryOption )*)? )? o {
|
|
247
248
|
if (count) {
|
|
248
249
|
// columns set because of $count: ignore $select, $expand, $top, $skip, $orderby
|
|
249
250
|
// REVISIT: don't ignore query options but throw bad request (as okra did)?
|
|
@@ -334,46 +335,39 @@
|
|
|
334
335
|
QueryOption = option:ExpandOption { if(option && option.apply) SELECT.apply = option.apply} /
|
|
335
336
|
"$skiptoken=" o skiptoken /
|
|
336
337
|
format /
|
|
337
|
-
custom
|
|
338
|
+
custom /
|
|
339
|
+
aliasedParamEqualsVal
|
|
338
340
|
// @OData spec for $expand:
|
|
339
341
|
// "Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, $expand and $apply (http://docs.oasis-open.org/odata/odata-data-aggregation-ext/v4.0/cs02/odata-data-aggregation-ext-v4.0-cs02.html#_The_expand_Transformation)."
|
|
340
342
|
ExpandOption =
|
|
341
343
|
"$select=" o select ( COMMA select )* /
|
|
342
|
-
"$expand=" o expand ( COMMA expand )* /
|
|
343
|
-
"$filter=" o f:filter{SELECT.where = f} /
|
|
344
|
+
"$expand=" o expand ( COMMA expand )* expandCount? /
|
|
345
|
+
"$filter=" o f:filter { SELECT.where = f } /
|
|
344
346
|
"$orderby=" o o:orderby ( COMMA o2:orderby{_setOrderBy(o2)} )* {_setOrderBy(o,true)} /
|
|
345
|
-
"$top=" o val:top{(SELECT.limit || (SELECT.limit={})).rows = {val}} /
|
|
346
|
-
"$skip=" o val:skip{_setLimitOffset(val)} /
|
|
347
|
-
"$search=" o s:search {if (s) SELECT.search = s} /
|
|
347
|
+
"$top=" o val:top { (SELECT.limit || (SELECT.limit={})).rows = {val} } /
|
|
348
|
+
"$skip=" o val:skip { _setLimitOffset(val) } /
|
|
349
|
+
"$search=" o s:search { if (s) SELECT.search = s } /
|
|
348
350
|
"$count=" o count /
|
|
349
|
-
"$apply=" o trafos:transformations {return trafos}
|
|
351
|
+
"$apply=" o trafos:transformations { return trafos }
|
|
350
352
|
|
|
351
353
|
|
|
352
354
|
select
|
|
353
|
-
= col:('*'/ref) {
|
|
355
|
+
= col:('*' / ref) {
|
|
354
356
|
SELECT.columns = Array.isArray(SELECT.columns) ? SELECT.columns : []
|
|
355
357
|
if (!SELECT.columns.find(_compareRefs(col))) SELECT.columns.push(col)
|
|
356
358
|
return col
|
|
357
359
|
}
|
|
358
360
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
)
|
|
370
|
-
( // --- nested query options, if any
|
|
371
|
-
(OPEN {
|
|
372
|
-
stack.push (SELECT)
|
|
373
|
-
SELECT = SELECT.expand[SELECT.expand.length-1]
|
|
374
|
-
SELECT.expand = '*' // by default expand everything
|
|
375
|
-
})(
|
|
376
|
-
expandOptions:( o ";"? o option:ExpandOption{return option})*
|
|
361
|
+
expandCount
|
|
362
|
+
= "/$count" {
|
|
363
|
+
const err = new Error("EXPAND_COUNT_UNSUPPORTED");
|
|
364
|
+
err.statusCode=501;
|
|
365
|
+
throw err;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
expandQueryOptions
|
|
369
|
+
= (
|
|
370
|
+
expandOptions:(option:ExpandOption o ";"? { return option })*
|
|
377
371
|
{
|
|
378
372
|
if (expandOptions.find(option => option && option.apply !== undefined)) {
|
|
379
373
|
const err = new Error("EXPAND_APPLY_UNSUPPORTED");
|
|
@@ -390,29 +384,50 @@
|
|
|
390
384
|
if (Array.isArray(SELECT.expand) && SELECT.expand.indexOf('*') === -1) SELECT.expand.unshift('*')
|
|
391
385
|
}
|
|
392
386
|
}
|
|
393
|
-
)
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
expandQueryOption
|
|
390
|
+
= (OPEN {
|
|
391
|
+
stack.push (SELECT)
|
|
392
|
+
SELECT = SELECT.expand[SELECT.expand.length-1]
|
|
393
|
+
SELECT.expand = '*' // by default expand everything
|
|
394
|
+
})
|
|
395
|
+
expandQueryOptions?
|
|
396
|
+
(CLOSE {
|
|
394
397
|
SELECT = stack.pop()
|
|
395
398
|
})
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
//REVISIT: per OData spec $apply should be also supported inside of $expand
|
|
402
|
+
expand
|
|
403
|
+
= (
|
|
404
|
+
c:('*' / ref) {
|
|
405
|
+
const col = c === '*' ? {} : c
|
|
406
|
+
col.expand = '*'
|
|
407
|
+
if (!Array.isArray(SELECT.expand)) SELECT.expand = []
|
|
408
|
+
if (!SELECT.expand.find(_compareRefs(col))) SELECT.expand.push(col)
|
|
409
|
+
return col
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
expandQueryOption?
|
|
413
|
+
|
|
403
414
|
top
|
|
404
|
-
= val:integer {return val}
|
|
415
|
+
= val:integer { return val }
|
|
416
|
+
|
|
405
417
|
skiptoken
|
|
406
418
|
= val:integer? skiptoken:skiptokenChars? {
|
|
407
419
|
// REVISIT ignore non-numeric $skiptoken as not supported by CQN
|
|
408
420
|
if (skiptoken) return
|
|
409
421
|
_setLimitOffset(val)
|
|
410
422
|
}
|
|
423
|
+
|
|
411
424
|
skip
|
|
412
|
-
= val:integer {return val}
|
|
425
|
+
= val:integer { return val }
|
|
426
|
+
|
|
413
427
|
search
|
|
414
428
|
= p:search_clause {return p}
|
|
415
429
|
/ o // Do not add search property for space only
|
|
430
|
+
|
|
416
431
|
search_clause
|
|
417
432
|
= p:( n:NOT? {return n?[n]:[]} )(
|
|
418
433
|
OPEN xpr:search_clause CLOSE {p.push({xpr})}
|
|
@@ -422,9 +437,11 @@
|
|
|
422
437
|
val:word {p.push({val})}
|
|
423
438
|
)
|
|
424
439
|
)( ao:(AND/OR/AND_SPACE) more:search_clause {p.push(ao,...more)} )*
|
|
425
|
-
{return p}
|
|
440
|
+
{ return p }
|
|
441
|
+
|
|
426
442
|
filter
|
|
427
443
|
= p:where_clause { return p }
|
|
444
|
+
|
|
428
445
|
where_clause = p:( n:NOT? {return n?[n]:[]} )(
|
|
429
446
|
OPEN xpr:where_clause CLOSE {p.push({xpr})}
|
|
430
447
|
/ comp:comparison {p.push(...comp)}
|
|
@@ -437,8 +454,10 @@
|
|
|
437
454
|
}
|
|
438
455
|
/ func:boolish {p.push(func)}
|
|
439
456
|
/ val:bool {p.push({val})}
|
|
457
|
+
/ list:listFilter {p.push(...list)}
|
|
440
458
|
)( ao:(AND/OR) more:where_clause {p.push(ao,...more)} )*
|
|
441
|
-
{return p}
|
|
459
|
+
{ return p }
|
|
460
|
+
|
|
442
461
|
lambda =
|
|
443
462
|
nav:( n:identifier {return[n]} ) '/' ( n:identifier '/' {nav.push(n)} )*
|
|
444
463
|
xpr:(
|
|
@@ -467,28 +486,48 @@
|
|
|
467
486
|
}
|
|
468
487
|
)
|
|
469
488
|
{ return xpr }
|
|
489
|
+
|
|
470
490
|
inner_lambda =
|
|
471
491
|
p:( n:NOT? { return n ? [n] : [] } )(
|
|
472
492
|
OPEN xpr:inner_lambda CLOSE { p.push('(', ...xpr, ')') }
|
|
473
493
|
/ comp:comparison { p.push(...comp) }
|
|
474
494
|
/ func:function { p.push(func) }
|
|
475
495
|
/ lambda:lambda { p.push(...lambda)}
|
|
496
|
+
/ list:listFilter {p.push(...list)}
|
|
476
497
|
)
|
|
477
498
|
( ao:(AND/OR) more:inner_lambda { p.push(ao, ...more) } )*
|
|
478
499
|
{ return p }
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
500
|
+
|
|
501
|
+
lambda_clause =
|
|
502
|
+
prefix:identifier ":" inner:inner_lambda {
|
|
503
|
+
return _removeLambdaPrefix(prefix, inner)
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
any =
|
|
507
|
+
"any" OPEN p:lambda_clause? CLOSE { return p }
|
|
508
|
+
|
|
509
|
+
all =
|
|
510
|
+
"all" OPEN p:lambda_clause CLOSE { return p }
|
|
511
|
+
|
|
484
512
|
orderby
|
|
485
|
-
= ref:(
|
|
513
|
+
= ref:(
|
|
514
|
+
lambda {
|
|
515
|
+
const err = new Error("ORDERBY_LAMBDA_UNSUPPORTED");
|
|
516
|
+
err.statusCode=501;
|
|
517
|
+
throw err;
|
|
518
|
+
} /
|
|
519
|
+
function /
|
|
520
|
+
ref
|
|
521
|
+
)
|
|
522
|
+
sort:( _ s:$("asc" / "desc") { return s })? {
|
|
486
523
|
// TODO: Lambda support
|
|
487
524
|
const appendObj = $(ref, sort && {sort});
|
|
488
525
|
return appendObj;
|
|
489
526
|
}
|
|
527
|
+
|
|
490
528
|
count
|
|
491
529
|
= val:bool { if(val) SELECT.count = true }
|
|
530
|
+
|
|
492
531
|
transformations
|
|
493
532
|
= mainTransformation:trafo additionalTransformation:("/" t2:trafo {
|
|
494
533
|
return t2
|
|
@@ -523,6 +562,8 @@
|
|
|
523
562
|
|
|
524
563
|
custom
|
|
525
564
|
= [a-zA-Z0-9-_.~]+ "=" [^&]*
|
|
565
|
+
aliasedParam "an aliased parameter (@param)" = "@" i:identifier { return "@" + i }
|
|
566
|
+
aliasedParamEqualsVal "@alias=value" = a:aliasedParam "=" v:([^&]*) {return a + "=" + v}
|
|
526
567
|
|
|
527
568
|
format = "$format=" f:$([^&]*) {
|
|
528
569
|
if (f.toLowerCase() !== "json") {
|
|
@@ -531,17 +572,25 @@
|
|
|
531
572
|
throw err;
|
|
532
573
|
}
|
|
533
574
|
}
|
|
575
|
+
|
|
534
576
|
//
|
|
535
577
|
// ---------- Expressions ------------
|
|
536
|
-
comparison
|
|
537
|
-
= a:operand _ o:$("eq"/"ne"/"lt"/"gt"/"le"/"ge") _ b:operand {
|
|
538
|
-
const op = { eq:'=', ne:'!=', lt:'<', gt:'>', le:'<=', ge:'>=' }[o]||o
|
|
578
|
+
comparison
|
|
579
|
+
= a:operand _ o:$("eq" / "ne" / "lt" / "gt" / "le" / "ge") _ b:operand {
|
|
580
|
+
const op = { eq:'=', ne:'!=', lt:'<', gt:'>', le:'<=', ge:'>=' }[o] || o
|
|
539
581
|
return [ a, op, b ]
|
|
540
582
|
}
|
|
583
|
+
|
|
584
|
+
listFilter
|
|
585
|
+
= a:operand _ "in" _ b:listRoundBrackets {
|
|
586
|
+
return [ a, "in", b ]
|
|
587
|
+
}
|
|
541
588
|
mathCalc
|
|
542
589
|
= operand (_ ("add" / "sub" / "mul" / "div" / "mod") _ operand)*
|
|
543
|
-
|
|
590
|
+
|
|
591
|
+
operand
|
|
544
592
|
= navigationCount / function / val / ref / jsonObject / jsonArray / list
|
|
593
|
+
|
|
545
594
|
navigationCount "navigation with $count"
|
|
546
595
|
= navigationPath:(head:identifier key:(OPEN keyArgs:args CLOSE {return keyArgs;})? '/' {
|
|
547
596
|
if (key) {
|
|
@@ -551,6 +600,7 @@
|
|
|
551
600
|
return head;
|
|
552
601
|
})+ count: '$count'
|
|
553
602
|
{ return {func: 'count', as: '$count', args: [{ref: navigationPath}]} }
|
|
603
|
+
|
|
554
604
|
ref "a reference"
|
|
555
605
|
= head:identifier tail:( '/' n:identifier {return n})*
|
|
556
606
|
{
|
|
@@ -559,34 +609,56 @@
|
|
|
559
609
|
}
|
|
560
610
|
return { ref:[ head, ...tail ] }
|
|
561
611
|
}
|
|
612
|
+
|
|
562
613
|
val
|
|
563
614
|
= val:(bool / date) {return {val}}
|
|
564
615
|
/ val:guid {return {val}}
|
|
565
616
|
/ val:number {return typeof val === 'number' ? {val} : { val, literal:'number' }}
|
|
566
617
|
/ val:string {return {val}}
|
|
567
618
|
/ val:binary {return {val}}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
619
|
+
/ val:aliasedParam {return {val}}
|
|
620
|
+
/ null
|
|
621
|
+
|
|
622
|
+
null "null" = "null" {return {val: null }}
|
|
623
|
+
|
|
624
|
+
jsonObject "a json object"
|
|
625
|
+
= val:$("{" (jsonObject / [^}])* "}") {return {val}}
|
|
626
|
+
|
|
627
|
+
jsonArray "a json array"
|
|
628
|
+
= val:$("[" o "]" / "[" o "{" (jsonArray / [^\]])* "]") {return {val}}
|
|
629
|
+
|
|
630
|
+
list "a list"
|
|
572
631
|
= "[" any:$([^\]])* "]" // > needs improvment
|
|
573
632
|
{ return { list: any.replace(/"/g,'').split(',').map(ele => ({ val: ele })) } }
|
|
574
633
|
|
|
575
|
-
|
|
576
|
-
=
|
|
634
|
+
listRoundBrackets "a list"
|
|
635
|
+
= OPEN list:(val1:val val2:("," v:val { return v })* { return [val1, ...val2] }) CLOSE // > needs improvment
|
|
636
|
+
{
|
|
637
|
+
return { list }
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
functionName "a function name"
|
|
642
|
+
= $[a-zA-Z]+
|
|
643
|
+
|
|
644
|
+
function
|
|
645
|
+
= func:functionName OPEN fnArgs:functionArgs CLOSE {
|
|
577
646
|
if (strict && !(func.toLowerCase() in strict.functions)) {
|
|
578
647
|
throw Object.assign(new Error(`"${func}" is an unknown function in OData URL spec (strict mode)`), { statusCode: 400 })
|
|
579
648
|
}
|
|
580
|
-
return { func: func.toLowerCase(), args:[a,...more] }
|
|
649
|
+
return { func: func.toLowerCase(), args:[fnArgs.a,...fnArgs.more] }
|
|
581
650
|
}
|
|
582
651
|
|
|
583
|
-
|
|
652
|
+
functionArgs
|
|
653
|
+
= a:operand more:( COMMA o:operand {return o} )* {return { a, more }}
|
|
654
|
+
|
|
655
|
+
boolish
|
|
584
656
|
= func:("contains"i/"endswith"i/"startswith"i) OPEN a:operand COMMA b:operand CLOSE
|
|
585
657
|
{ return { func: func.toLowerCase(), args:[a,b] }}
|
|
586
658
|
|
|
587
659
|
NOT = o "NOT"i _ {return 'not'}
|
|
588
660
|
AND = _ "AND"i _ {return 'and'}
|
|
589
|
-
AND_SPACE =
|
|
661
|
+
AND_SPACE = _ {return 'and'}
|
|
590
662
|
OR = _ "OR"i _ {return 'or'}
|
|
591
663
|
|
|
592
664
|
|
|
@@ -622,7 +694,7 @@
|
|
|
622
694
|
}
|
|
623
695
|
return {aggregate: [{ func, args }]}
|
|
624
696
|
} /
|
|
625
|
-
identity: identityTrafo{return identity}
|
|
697
|
+
identity: identityTrafo {return identity}
|
|
626
698
|
// customFunction
|
|
627
699
|
)
|
|
628
700
|
|
|
@@ -663,7 +735,11 @@
|
|
|
663
735
|
groupByElem
|
|
664
736
|
= c:(rollupSpec / ref) { return c }
|
|
665
737
|
rollupSpec // TODO fix this + add CAP support
|
|
666
|
-
= rollup:("rollup" OPEN o ('$all' / ref) (o COMMA ref)+ o CLOSE) {
|
|
738
|
+
= rollup:("rollup" OPEN o ('$all' / ref) (o COMMA ref)+ o CLOSE) {
|
|
739
|
+
const err = new Error("Rollup in groupby is not supported yet.");
|
|
740
|
+
err.statusCode=501;
|
|
741
|
+
throw err;
|
|
742
|
+
}
|
|
667
743
|
|
|
668
744
|
filterTrafo = OPEN o where:(where:filter{
|
|
669
745
|
return where
|
|
@@ -707,20 +783,21 @@
|
|
|
707
783
|
//
|
|
708
784
|
// ---------- Literals -----------
|
|
709
785
|
|
|
710
|
-
bool
|
|
786
|
+
bool "a boolean"
|
|
787
|
+
= b:("true" / "false") { return b === 'true'}
|
|
711
788
|
|
|
712
|
-
string "Edm.String"
|
|
713
|
-
= "'" s:$("''"/[^'])* "'"
|
|
789
|
+
string "a single quoted string" // "Edm.String"
|
|
790
|
+
= "'" s:$("''" / [^'])* "'" // 'A user''s story'
|
|
714
791
|
{return s.replace(/''/g,"'")}
|
|
715
792
|
|
|
716
|
-
doubleQuotedString
|
|
793
|
+
doubleQuotedString "a doubled quoted string"
|
|
717
794
|
= '"' s:$('\\"'/[^"])* '"'
|
|
718
795
|
{return s.replace(/\\\\/g,"\\").replace(/\\"/g,'"')}
|
|
719
796
|
|
|
720
|
-
word
|
|
797
|
+
word "a string"
|
|
721
798
|
= $([^ \t\n()"&;]+)
|
|
722
799
|
|
|
723
|
-
date
|
|
800
|
+
date "a date"
|
|
724
801
|
= s:$( [0-9]+"-"[0-9][0-9]"-"[0-9][0-9] // date
|
|
725
802
|
( "T"[0-9][0-9]":"[0-9][0-9](":"[0-9][0-9]("."[0-9]+)?)? // time
|
|
726
803
|
( "Z" / (("+" / "-")[0-9][0-9]":"[0-9][0-9]) )? // timezone (Z or +-hh:mm)
|
|
@@ -730,19 +807,23 @@
|
|
|
730
807
|
return s
|
|
731
808
|
}
|
|
732
809
|
|
|
733
|
-
number
|
|
734
|
-
|
|
810
|
+
// to avoid 123-123-123 being matched as number and showing error for "-123-123"
|
|
811
|
+
endsWithMinus
|
|
812
|
+
= [0-9]+ "-"
|
|
813
|
+
|
|
814
|
+
number "a number"
|
|
815
|
+
= !endsWithMinus s:$( [+-]? [0-9]+ ("."[0-9]+)? ("e"[0-9]+)? ) { return safeNumber(s) }
|
|
735
816
|
|
|
736
|
-
integer
|
|
817
|
+
integer "an integer"
|
|
737
818
|
= s:$( [+-]? [0-9]+ ) { return parseInt(s) }
|
|
738
819
|
|
|
739
|
-
identifier
|
|
820
|
+
identifier "an identifier"
|
|
740
821
|
= !bool !guid s:$([_a-zA-Z][_a-zA-Z0-9"."]*) { return s }
|
|
741
822
|
|
|
742
|
-
guid
|
|
823
|
+
guid "a guid"
|
|
743
824
|
= $( hex16 hex16 "-"? hex16 "-"? hex16 "-"? hex16 "-"? hex16 hex16 hex16 )
|
|
744
825
|
|
|
745
|
-
hex16
|
|
826
|
+
hex16 "a hex value"
|
|
746
827
|
= $( [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] )
|
|
747
828
|
|
|
748
829
|
segment // > everything except / and ?
|
|
@@ -751,7 +832,7 @@
|
|
|
751
832
|
skiptokenChars
|
|
752
833
|
= $( [a-zA-Z0-9-"."_~!$'()*+,;=:@"/""?"]+ )
|
|
753
834
|
|
|
754
|
-
binary // > url-safe base64
|
|
835
|
+
binary "a binary" // > url-safe base64
|
|
755
836
|
= "binary'" s:$([a-zA-Z0-9-_]+ ("=="/"=")?) "'" { return standardBase64(s) }
|
|
756
837
|
|
|
757
838
|
//
|
|
@@ -766,8 +847,8 @@
|
|
|
766
847
|
//
|
|
767
848
|
// ---------- Whitespaces -----------
|
|
768
849
|
|
|
769
|
-
o "optional
|
|
770
|
-
_ "
|
|
850
|
+
o "an optional whitespace" = $[ \t\n]*
|
|
851
|
+
_ "a whitespace" = $[ \t\n]+
|
|
771
852
|
|
|
772
853
|
//
|
|
773
|
-
// ------------------------------------
|
|
854
|
+
// ------------------------------------
|
package/libx/odata/index.js
CHANGED
|
@@ -74,12 +74,18 @@ module.exports = {
|
|
|
74
74
|
try {
|
|
75
75
|
cqn = odata2cqn(url, options)
|
|
76
76
|
} catch (err) {
|
|
77
|
-
if (err.
|
|
78
|
-
throw getError(err.statusCode
|
|
77
|
+
if (err.statusCode === 501) {
|
|
78
|
+
throw getError(err.statusCode, err.message)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let offset = err.location && err.location.start.offset
|
|
82
|
+
if (options.baseUrl) {
|
|
83
|
+
// we need to add the number of chars from base url to the offset
|
|
84
|
+
offset += options.baseUrl.length
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
// TODO adjust this to behave like above
|
|
82
|
-
err.message =
|
|
88
|
+
err.message = `Parsing URL failed at position ${offset}: ${err.message}`
|
|
83
89
|
err.statusCode = err.statusCode || 400
|
|
84
90
|
throw err
|
|
85
91
|
}
|