@sap/cds-dk 10.0.7 → 10.1.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 +94 -0
- package/bin/add.js +7 -23
- package/bin/bind.js +10 -0
- package/bin/build.js +20 -34
- package/bin/cds.js +1 -1
- package/bin/compile/index.js +15 -41
- package/bin/completion/completionFs.js +11 -8
- package/bin/completion/index.js +592 -80
- package/bin/completion/scripts/cds.fish +568 -0
- package/bin/completion/scripts/cds.ps1 +329 -0
- package/bin/completion/scripts/cds.sh +261 -0
- package/bin/completion/scripts/cds.zsh +230 -0
- package/bin/completion/templates/cds-tmpl.fish +65 -0
- package/bin/completion/templates/cds-tmpl.ps1 +208 -0
- package/bin/completion/templates/cds-tmpl.sh +93 -0
- package/bin/completion/templates/cds-tmpl.zsh +74 -0
- package/bin/deploy/index.js +7 -1
- package/bin/deploy/options.js +25 -0
- package/{lib → bin}/deploy/to-hana/hana.js +8 -8
- package/{lib → bin}/deploy/to-hana/hdiDeployUtil.js +1 -1
- package/bin/deploy/{to-hana.js → to-hana/index.js} +1 -1
- package/{lib → bin}/deploy/to-hana/mtaUtil.js +1 -1
- package/bin/deploy/to-sql.js +0 -2
- package/bin/export.js +35 -5
- package/bin/help/export.md +3 -0
- package/bin/help.js +1 -5
- package/bin/import.js +6 -0
- package/bin/init.js +5 -24
- package/bin/inspect.js +6 -0
- package/bin/login.js +26 -20
- package/bin/pull.js +19 -6
- package/bin/push.js +19 -6
- package/bin/up.js +14 -11
- package/{lib → bin}/upgrade/constants.js +1 -1
- package/bin/{upgrade.js → upgrade/index.js} +2 -2
- package/{lib → bin}/upgrade/preflight/consistency.js +1 -1
- package/{lib → bin}/upgrade/preflight/index.js +1 -1
- package/{lib → bin}/upgrade/steps/analyze/index.js +1 -1
- package/{lib → bin}/upgrade/steps/install.js +1 -1
- package/{lib → bin}/upgrade/steps/openrewrite.js +1 -1
- package/{lib → bin}/upgrade/steps/removals.js +1 -1
- package/{lib → bin}/upgrade/steps/rewrite.js +1 -1
- package/{lib → bin}/upgrade/steps/verify.js +1 -1
- package/{lib/upgrade/index.js → bin/upgrade/upgrade.js} +2 -2
- package/{lib → bin}/upgrade/util/pom.js +2 -2
- package/{lib → bin}/upgrade/util/prompt.js +1 -1
- package/bin/util/containerize.js +8 -4
- package/bin/version.js +10 -1
- package/{lib → bin}/watch/hot-reload.js +1 -1
- package/bin/{watch.js → watch/index.js} +17 -9
- package/{lib → bin}/watch/livereload-connect.js +1 -1
- package/{lib → bin}/watch/vite-watch.js +1 -1
- package/{lib → bin}/watch/watched.js +2 -2
- package/lib/build/constants.js +1 -1
- package/lib/build/plugins/fiori/index.js +31 -2
- package/lib/build/plugins/internal.js +4 -2
- package/lib/build/plugins/mtx-sidecar/index.js +7 -8
- package/lib/build/plugins/nodejs/index.js +64 -7
- package/lib/compile/to_asyncapi.js +1 -1
- package/lib/env/schema.js +16 -0
- package/lib/env/schemas/cds-rc.js +1 -76
- package/lib/import/importapi.js +2 -3
- package/lib/import/message.js +0 -2
- package/lib/init/constants.js +2 -1
- package/lib/init/index.js +2 -2
- package/lib/init/merge.js +123 -280
- package/lib/init/plugin.js +3 -1
- package/lib/init/projectReader.js +22 -6
- package/lib/init/registries/xs-app.js +3 -5
- package/lib/init/template/ai/files/mta.yaml.hbs +1 -1
- package/lib/init/template/ai/index.js +14 -2
- package/lib/init/template/ams/index.js +2 -2
- package/lib/init/template/app-frontend/files/containerize.yaml.hbs +2 -2
- package/lib/init/template/app-frontend/index.js +4 -4
- package/lib/init/template/application-logging/index.js +2 -2
- package/lib/init/template/approuter/files/package.json +1 -1
- package/lib/init/template/approuter/index.js +8 -3
- package/lib/init/template/attachments/files/package.json.hbs +1 -1
- package/lib/init/template/attachments/index.js +2 -2
- package/lib/init/template/audit-logging/index.js +2 -2
- package/lib/init/template/cloud-logging/files/package.json.hbs +4 -4
- package/lib/init/template/cloud-logging/index.js +2 -2
- package/lib/init/template/completion/completionSetup.js +36 -39
- package/lib/init/template/connectivity/index.js +2 -2
- package/lib/init/template/data/as-csv.js +15 -5
- package/lib/init/template/data/as-json.js +114 -42
- package/lib/init/template/data/index.js +16 -2
- package/lib/init/template/destination/index.js +2 -2
- package/lib/init/template/dynatrace/files/package.json.hbs +3 -3
- package/lib/init/template/dynatrace/index.js +2 -2
- package/lib/init/template/enterprise-messaging/index.js +2 -2
- package/lib/init/template/enterprise-messaging-shared/index.js +2 -2
- package/lib/init/template/extensibility/files/mta.yaml.hbs +11 -0
- package/lib/init/template/extensibility/files/xs-security.json.hbs +1 -1
- package/lib/init/template/extensibility/index.js +3 -3
- package/lib/init/template/github-actions/index.js +2 -2
- package/lib/init/template/hana/index.js +3 -2
- package/lib/init/template/hana-serverless/files/db/package.json +14 -0
- package/lib/init/template/hana-serverless/files/identity.values.yaml.hbs +10 -0
- package/lib/init/template/hana-serverless/files/mta.yaml.hbs +64 -0
- package/lib/init/template/hana-serverless/files/package.json.hbs +35 -0
- package/lib/init/template/hana-serverless/files/src/.hdiconfig +139 -0
- package/lib/init/template/hana-serverless/files/undeploy.json +7 -0
- package/lib/init/template/hana-serverless/files/values.yaml.hbs +18 -0
- package/lib/init/template/hana-serverless/index.js +184 -0
- package/lib/init/template/html5-repo/files/containerize.yaml.hbs +2 -2
- package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -0
- package/lib/init/template/html5-repo/index.js +18 -14
- package/lib/init/template/http/index.js +123 -26
- package/lib/init/template/ias/index.js +2 -2
- package/lib/init/template/kafka/index.js +2 -2
- package/lib/init/template/kyma/index.js +7 -5
- package/lib/init/template/malware-scanner/index.js +2 -2
- package/lib/init/template/mta/files/mta.yaml.hbs +1 -1
- package/lib/init/template/multitenancy/index.js +18 -3
- package/lib/init/template/notifications/index.js +2 -2
- package/lib/init/template/portal/files/mta.yaml.hbs +4 -0
- package/lib/init/template/portal/index.js +13 -8
- package/lib/init/template/postgres/index.js +2 -2
- package/lib/init/template/redis/index.js +2 -2
- package/lib/init/template/sample/files/db/currencies.cds +2 -0
- package/lib/init/template/sample/files/db/data/sap.capire.bookshop-Authors.csv +1 -1
- package/lib/init/template/tiny-sample/files/nodejs/db/data/CatalogService.Books.csv +2 -2
- package/lib/init/template/workzone-standard/index.js +5 -5
- package/lib/init/template/xsuaa/index.js +20 -2
- package/lib/lint/eslintHelp.json +1 -1
- package/lib/mtx/auth_manager.js +103 -37
- package/lib/mtx/params.js +3 -2
- package/lib/mtx/settings_manager.js +45 -28
- package/lib/mtx/tenant_action.js +0 -1
- package/lib/mtx/util/credentials.js +62 -0
- package/node_modules/@sap/cds/CHANGELOG.md +57 -0
- package/node_modules/@sap/cds/app/index.js +5 -4
- package/node_modules/@sap/cds/eslint.config.mjs +1 -0
- package/node_modules/@sap/cds/lib/compile/minify.js +14 -10
- package/node_modules/@sap/cds/lib/env/cds-env.js +1 -1
- package/node_modules/@sap/cds/lib/env/cds-requires.js +22 -11
- package/node_modules/@sap/cds/lib/env/defaults.js +4 -1
- package/node_modules/@sap/cds/lib/env/schemas/cds-rc.js +5 -2
- package/node_modules/@sap/cds/lib/plugins.js +9 -5
- package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
- package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +1 -1
- package/node_modules/@sap/cds/lib/srv/srv-models.js +1 -1
- package/node_modules/@sap/cds/lib/utils/cds-utils.js +2 -1
- package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +2 -3
- package/node_modules/@sap/cds/libx/_runtime/common/generic/auth/restrict.js +8 -1
- package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +18 -8
- package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +25 -17
- package/node_modules/@sap/cds/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +9 -3
- package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +4 -19
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/LruCache.js +42 -0
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +14 -4
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/cloudSdkProvider.js +2 -9
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/destinationClient.js +150 -0
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/error.js +13 -0
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/fetchClient.js +26 -18
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +34 -23
- package/node_modules/@sap/cds/libx/_runtime/remote/utils/token.js +82 -0
- package/node_modules/@sap/cds/libx/_runtime/ucl/Service.js +36 -189
- package/node_modules/@sap/cds/libx/common/utils/streaming.js +16 -16
- package/node_modules/@sap/cds/libx/http/location.js +3 -3
- package/node_modules/@sap/cds/libx/odata/middleware/batch.js +16 -10
- package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +9 -6
- package/node_modules/@sap/cds/libx/odata/middleware/service-document.js +1 -1
- package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +19 -3
- package/node_modules/@sap/cds/libx/odata/parse/cqn2odata.js +83 -86
- package/node_modules/@sap/cds/libx/queue/SchedulingService.js +17 -2
- package/node_modules/@sap/cds/libx/queue/processing.js +1 -3
- package/node_modules/@sap/cds/libx/rest/RestAdapter.js +3 -7
- package/node_modules/@sap/cds/libx/rest/middleware/delete.js +3 -3
- package/node_modules/@sap/cds/libx/rest/middleware/parse.js +13 -8
- package/node_modules/@sap/cds/libx/rest/middleware/read.js +3 -3
- package/node_modules/@sap/cds/libx/rest/middleware/upsert.js +2 -2
- package/node_modules/@sap/cds/package.json +1 -1
- package/node_modules/@sap/cds-compiler/CHANGELOG.md +60 -8
- package/node_modules/@sap/cds-compiler/bin/cdsc.js +2 -2
- package/node_modules/@sap/cds-compiler/doc/IncompatibleChanges_v7.md +46 -19
- package/node_modules/@sap/cds-compiler/lib/api/main.js +10 -7
- package/node_modules/@sap/cds-compiler/lib/api/options.js +8 -2
- package/node_modules/@sap/cds-compiler/lib/base/csnRefs.js +5 -2
- package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +4 -0
- package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +12 -0
- package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +8 -7
- package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +3 -3
- package/node_modules/@sap/cds-compiler/lib/compiler/define.js +301 -75
- package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +2 -0
- package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +40 -26
- package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +45 -60
- package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +16 -7
- package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +41 -15
- package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +7 -6
- package/node_modules/@sap/cds-compiler/lib/compiler/tweak-assocs.js +62 -50
- package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +29 -14
- package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +6 -5
- package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
- package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +1119 -1109
- package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +19 -3
- package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +10 -16
- package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +58 -39
- package/node_modules/@sap/cds-compiler/lib/main.d.ts +8 -0
- package/node_modules/@sap/cds-compiler/lib/main.js +1 -0
- package/node_modules/@sap/cds-compiler/lib/model/csnUtils.js +2 -0
- package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/parsers/XprTree.js +8 -0
- package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +22 -1
- package/node_modules/@sap/cds-compiler/lib/render/toSql.js +17 -2
- package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +6 -1
- package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +27 -0
- package/node_modules/@sap/cds-compiler/lib/render/utils/standardDatabaseFunctions.js +125 -3
- package/node_modules/@sap/cds-compiler/lib/tool-lib/revealInternalProperties.js +2 -1
- package/node_modules/@sap/cds-compiler/lib/transform/db/applyTransformations.js +3 -0
- package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +8 -2
- package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +22 -6
- package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +62 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
- package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +1 -0
- package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +6 -1
- package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +19 -8
- package/node_modules/@sap/cds-compiler/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/CHANGELOG.md +15 -0
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +34 -16
- package/node_modules/@sap/cds-mtxs/lib/utils.js +19 -4
- package/node_modules/@sap/cds-mtxs/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +22 -13
- package/node_modules/@sap/cds-mtxs/srv/model-provider.js +17 -2
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +4 -8
- package/node_modules/@sap/xsenv/CHANGELOG.md +7 -0
- package/node_modules/@sap/xsenv/package.json +10 -7
- package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
- package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
- package/node_modules/hdb/cfg/VERSION +1 -1
- package/node_modules/hdb/lib/protocol/ClientInfo.js +16 -3
- package/node_modules/hdb/lib/protocol/Connection.js +1 -0
- package/node_modules/hdb/package.json +3 -2
- package/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/negotiator/package.json +16 -10
- package/node_modules/qs/.github/THREAT_MODEL.md +3 -3
- package/node_modules/qs/CHANGELOG.md +15 -0
- package/node_modules/qs/README.md +19 -1
- package/node_modules/qs/dist/qs.js +21 -21
- package/node_modules/qs/eslint.config.mjs +1 -1
- package/node_modules/qs/lib/parse.js +3 -4
- package/node_modules/qs/lib/stringify.js +23 -8
- package/node_modules/qs/lib/utils.js +10 -3
- package/node_modules/qs/package.json +4 -4
- package/node_modules/qs/test/parse.js +192 -3
- package/node_modules/qs/test/stringify.js +317 -0
- package/node_modules/qs/test/utils.js +12 -0
- package/node_modules/type-is/node_modules/content-type/README.md +2 -0
- package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/type-is/node_modules/content-type/package.json +1 -1
- package/node_modules/ws/lib/permessage-deflate.js +3 -1
- package/node_modules/ws/package.json +1 -1
- package/package.json +3 -3
- package/bin/completion/scripts/cds-bash.sh +0 -20
- package/bin/completion/scripts/cds-fish.fish +0 -13
- package/bin/completion/scripts/cds-ps.ps1 +0 -19
- package/bin/completion/scripts/cds-zsh.sh +0 -13
- package/lib/deploy/index.js +0 -25
- package/lib/import/asyncapi/importAsyncAPI.js +0 -33
- package/lib/import/asyncapi/index.js +0 -18
- package/lib/import/asyncapi/parserContext.js +0 -454
- package/lib/import/asyncapi/utils.js +0 -49
- package/node_modules/@sap/cds/libx/_runtime/ucl/queries.js +0 -61
- package/node_modules/negotiator/HISTORY.md +0 -114
- /package/{lib → bin}/upgrade/context.js +0 -0
- /package/{lib → bin}/upgrade/migrations/cds10/migrations.json +0 -0
- /package/{lib → bin}/upgrade/preflight/cds-version.js +0 -0
- /package/{lib → bin}/upgrade/preflight/project-type.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/classification.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/detector.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/evaluator.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/reporter.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/setup.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/utils/detection.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/utils/files.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/utils/grep.js +0 -0
- /package/{lib → bin}/upgrade/steps/analyze/utils/yaml.js +0 -0
- /package/{lib → bin}/upgrade/util/workspaces.js +0 -0
- /package/{lib → bin}/watch/esm-resolve-registration.js +0 -0
- /package/{lib → bin}/watch/livereload-server.js +0 -0
- /package/{lib → bin}/watch/node-watch.js +0 -0
- /package/{lib → bin}/watch/open.js +0 -0
- /package/{lib → bin}/watch/watcher.js +0 -0
|
@@ -35,11 +35,11 @@ module.exports = exports = {
|
|
|
35
35
|
sql_simple_queries: 0,
|
|
36
36
|
pre_compile_edmxs: false,
|
|
37
37
|
live_reload: !production,
|
|
38
|
-
in_memory_db: !production,
|
|
39
38
|
test_data: !production,
|
|
40
39
|
test_mocks: !production,
|
|
41
40
|
with_mocks: !production,
|
|
42
41
|
mocked_bindings: !production,
|
|
42
|
+
in_memory_db: true,
|
|
43
43
|
// skip_unused: 'all',
|
|
44
44
|
skip_unused: true,
|
|
45
45
|
deploy_data_onconflict: 'insert',
|
|
@@ -223,6 +223,9 @@ module.exports = exports = {
|
|
|
223
223
|
|
|
224
224
|
remote: {
|
|
225
225
|
native_fetch: undefined,
|
|
226
|
+
timeout: '10s',
|
|
227
|
+
cache_size: 0,
|
|
228
|
+
cache_expiry_buffer: '5min',
|
|
226
229
|
},
|
|
227
230
|
|
|
228
231
|
}
|
|
@@ -3,6 +3,7 @@ const cds = require('../../index')
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
_version: cds.version,
|
|
5
5
|
|
|
6
|
+
$id: 'cdsjsonschema://schemas/cds-rc.json',
|
|
6
7
|
title: 'JSON schema for CDS configuration',
|
|
7
8
|
$schema: 'https://json-schema.org/draft-07/schema',
|
|
8
9
|
description: 'This is a JSON schema representation for CDS project configuration',
|
|
@@ -961,12 +962,14 @@ module.exports = {
|
|
|
961
962
|
enum: [
|
|
962
963
|
'hana',
|
|
963
964
|
'sql',
|
|
964
|
-
'sqlite'
|
|
965
|
+
'sqlite',
|
|
966
|
+
'sqlite:memory'
|
|
965
967
|
],
|
|
966
968
|
enumDescriptions: [
|
|
967
969
|
'SAP HANA',
|
|
968
970
|
'In-memory SQLite (development), SAP HANA (production)',
|
|
969
|
-
'File-based SQLite'
|
|
971
|
+
'File-based SQLite',
|
|
972
|
+
'In-memory SQLite'
|
|
970
973
|
]
|
|
971
974
|
},
|
|
972
975
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
const DEBUG = /\b(y|all|plugins)\b/.test(process.env.DEBUG) ? console : undefined // eslint-disable-line no-console
|
|
2
2
|
const cds = require('.')
|
|
3
3
|
|
|
4
|
+
const prioritized = {
|
|
5
|
+
'@sap/cds-mtxs': true, // plugins may register handlers for mtxs services
|
|
6
|
+
'@cap-js/sqlite': true, // to enable override by @cap-js/ai
|
|
7
|
+
'@cap-js/telemetry': true // to allow better instrumentation
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
11
|
* Fetch cds-plugins from project's package dependencies.
|
|
6
12
|
* Called in cds.env to populate the plugins configuration
|
|
@@ -8,7 +14,7 @@ const cds = require('.')
|
|
|
8
14
|
*/
|
|
9
15
|
exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
|
|
10
16
|
DEBUG?.time ('[cds.plugins] - fetched plugins in')
|
|
11
|
-
|
|
17
|
+
let plugins = JSON.parse(process.env.CDS_PLUGINS||'{}')
|
|
12
18
|
fetch_plugins_in (cds.home, false)
|
|
13
19
|
fetch_plugins_in (cds.root, DEV)
|
|
14
20
|
function fetch_plugins_in (root, dev) {
|
|
@@ -19,6 +25,8 @@ exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
|
|
|
19
25
|
plugins[each] = { impl }
|
|
20
26
|
} catch { /* no cds-plugin.js */ }
|
|
21
27
|
}
|
|
28
|
+
for (const each in prioritized)
|
|
29
|
+
if (each in plugins) plugins = Object.assign({ [each]: plugins[each] }, plugins)
|
|
22
30
|
DEBUG?.timeEnd ('[cds.plugins] - fetched plugins in')
|
|
23
31
|
return plugins
|
|
24
32
|
}
|
|
@@ -30,10 +38,6 @@ exports.fetch = function (DEV = process.env.NODE_ENV !== 'production') {
|
|
|
30
38
|
exports.activate = async function (plugins = cds.env?.plugins || exports.fetch()) {
|
|
31
39
|
DEBUG?.time ('[cds.plugins] - loaded plugins in')
|
|
32
40
|
const all = Object.entries(plugins), { local } = cds.utils
|
|
33
|
-
const prioritized = {
|
|
34
|
-
'@sap/cds-mtxs': true, // plugins may register handlers for mtxs services
|
|
35
|
-
'@cap-js/telemetry': true // to allow better instrumentation
|
|
36
|
-
}
|
|
37
41
|
await Promise.all (all.map (([n,c]) => n in prioritized && _load(n,c)))
|
|
38
42
|
await Promise.all (all.map (([n,c]) => n in prioritized || _load(n,c)))
|
|
39
43
|
async function _load (plugin, conf) {
|
|
@@ -12,7 +12,7 @@ module.exports = function spawn (o, fn, /** @type {import('../index')} */ cds=th
|
|
|
12
12
|
if (cds.model && (cds.env.requires.extensibility || cds.env.requires.toggles)) {
|
|
13
13
|
const ctx = cds.context
|
|
14
14
|
const ExtendedModels = require('../srv/srv-models') // the sentinel is automatically started when required
|
|
15
|
-
cds.context.model = await ExtendedModels.model4(ctx.tenant, ctx.features)
|
|
15
|
+
cds.context.model = await cds.tx(() => ExtendedModels.model4(ctx.tenant, ctx.features))
|
|
16
16
|
tx.model = cds.context.model
|
|
17
17
|
}
|
|
18
18
|
return Promise.resolve(fn(tx))
|
|
@@ -113,5 +113,5 @@ const _ensure_fqn = (x,p,srv, name = x[p]) => {
|
|
|
113
113
|
|
|
114
114
|
const _unhandled = (srv,req) => {
|
|
115
115
|
const event = req.event + (req.path ? ' ' + req.path : '')
|
|
116
|
-
|
|
116
|
+
cds.error (501, `Service "${srv.name}" has no handler for "${event}".`)
|
|
117
117
|
}
|
|
@@ -148,7 +148,7 @@ if (!extensibility) {
|
|
|
148
148
|
// helper to get model for tenant/features
|
|
149
149
|
const _is_extended = extensibility ? ()=> cds.db.exists('cds.xt.Extensions') : ()=> false
|
|
150
150
|
const _get_model4 = async (tenant, features) => {
|
|
151
|
-
const
|
|
151
|
+
const mps = await cds.connect.to('cds.xt.ModelProviderService')
|
|
152
152
|
const csn = await mps.getCsn (tenant, features)
|
|
153
153
|
const nsn = cds.compile.for.nodejs(csn)
|
|
154
154
|
if (cds.edmxs) await cds.compile.to.edmx.files ( csn,
|
|
@@ -389,7 +389,8 @@ exports.sh = function shell (cmd,..._) {
|
|
|
389
389
|
*/
|
|
390
390
|
const ms4 = exports.ms4 = (ts, unit, u=unit) => {
|
|
391
391
|
if (typeof ts === 'string') [,ts,u] = /(\d+) ?(\w*)/.exec(ts) || cds.error `Invalid time span format: ${ts}`
|
|
392
|
-
|
|
392
|
+
const factor = ms4[u||unit||'ms'] || cds.error `Invalid time span unit: ${unit} in ${ts}`
|
|
393
|
+
return ts * factor
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
/**
|
|
@@ -132,9 +132,8 @@ module.exports = cds.service.impl(function () {
|
|
|
132
132
|
// If error function was used in @assert expression -> use its output
|
|
133
133
|
// Note: depending on DB, function result may be JavaScript object or JSON string
|
|
134
134
|
if (typeof message === 'string') {
|
|
135
|
-
if (message[0]
|
|
136
|
-
|
|
137
|
-
else return error //> it's a plain message string
|
|
135
|
+
if (message[0] !== '{' || message.startsWith('{i18n>')) return error //> it's a plain message string
|
|
136
|
+
message = JSON.parse(message) //> it's an error function result
|
|
138
137
|
}
|
|
139
138
|
let { targets = [], ...details } = message
|
|
140
139
|
if (targets.length) details.target = targets.shift()
|
|
@@ -238,7 +238,14 @@ async function enforce_auth(req) {
|
|
|
238
238
|
// REVISIT with cds^11
|
|
239
239
|
// - remove compat_static_auth
|
|
240
240
|
// - make check on CREATE/ NEW and unbound a compat opt-in
|
|
241
|
-
|
|
241
|
+
const boundAction = req.target?.actions?.[req.event]
|
|
242
|
+
if (
|
|
243
|
+
cds.env.features.compat_static_auth ||
|
|
244
|
+
req.event in { CREATE: 1, NEW: 1 } ||
|
|
245
|
+
this.operations[req.event] ||
|
|
246
|
+
// collection-bound actions have no instance to filter -> only a static where can apply
|
|
247
|
+
(boundAction && isBoundToCollection(boundAction))
|
|
248
|
+
) {
|
|
242
249
|
const staticAuthRestriction = _getStaticAuthRestrictions(resolvedApplicables)
|
|
243
250
|
if (staticAuthRestriction.length > 0) {
|
|
244
251
|
return _handleStaticAuthRestrictions(staticAuthRestriction, req)
|
|
@@ -2,6 +2,8 @@ const cds = require('../../cds')
|
|
|
2
2
|
const { SELECT } = cds.ql
|
|
3
3
|
|
|
4
4
|
module.exports = exports = cds.service.impl(function () {
|
|
5
|
+
const { parent_skip_auth } = cds.env.features
|
|
6
|
+
|
|
5
7
|
// prettier-ignore
|
|
6
8
|
this.on(['CREATE', 'READ', 'UPDATE', 'UPSERT', 'DELETE'], '*', async function handle_crud_requests(req) {
|
|
7
9
|
if (!cds.db)
|
|
@@ -11,18 +13,26 @@ module.exports = exports = cds.service.impl(function () {
|
|
|
11
13
|
if (req.target['@cds.persistence.skip'] === true && req.target['@cds.persistence.table'] !== true)
|
|
12
14
|
return req.reject(501, `Entity "${req.target.name}" is annotated with "@cds.persistence.skip" and cannot be served generically.`)
|
|
13
15
|
|
|
14
|
-
const { ref } = req.query
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { ref } = req.query?.INSERT?.into || req.query?.SELECT?.from || {}
|
|
17
|
+
const parent_exists_query = ref?.length > 1 && !('$parent' in (req.query?.elements ?? {}))
|
|
18
|
+
? SELECT.one`1 as $parent`.from({ ref: ref.slice(0, -1) })
|
|
19
|
+
: null
|
|
20
|
+
const parent_readable_check = parent_exists_query
|
|
21
|
+
? async () => (parent_skip_auth ? cds.db : this).run(parent_exists_query).catch(() => null)
|
|
22
|
+
: null
|
|
23
|
+
|
|
24
|
+
if (req.event === 'CREATE' && parent_readable_check != null) (await parent_readable_check()) || req.reject(404)
|
|
25
|
+
|
|
26
|
+
if (req.target?._isSingleton) await handle_singleton_request(req)
|
|
27
|
+
|
|
28
|
+
if (req.query?.SELECT && req.locale) req.query.SELECT.localized ??= true
|
|
19
29
|
|
|
20
30
|
// REVISIT for cds^10: can we always use cds.db.dispatch(req)?
|
|
21
31
|
const result = req.iterator && !req.objectMode
|
|
22
32
|
? await cds.db.dispatch(req)
|
|
23
33
|
: await cds.run(req.query, req.data)
|
|
24
34
|
|
|
25
|
-
return await exports._handle_result(req, result,
|
|
35
|
+
return await exports._handle_result(req, result, parent_readable_check)
|
|
26
36
|
})
|
|
27
37
|
})
|
|
28
38
|
|
|
@@ -42,14 +52,14 @@ async function handle_singleton_request(req) {
|
|
|
42
52
|
req.query.where(singleton)
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
async function new_behavior(req, result,
|
|
55
|
+
async function new_behavior(req, result, parent_readable_check) {
|
|
46
56
|
const n = result?.affected ?? result?.length ?? result
|
|
47
57
|
|
|
48
58
|
// prettier-ignore
|
|
49
59
|
switch (req.event) {
|
|
50
60
|
case 'READ':
|
|
51
61
|
if (!n && req._etagValidationType === 'if-match') req.reject(412)
|
|
52
|
-
if (!n
|
|
62
|
+
if (!n && parent_readable_check != null) (await parent_readable_check()) || req.reject(404)
|
|
53
63
|
return result
|
|
54
64
|
case 'INSERT': case 'CREATE':
|
|
55
65
|
if (result.affected != null) return result //> db service returned [affected]
|
|
@@ -453,7 +453,7 @@ const compileUpdatedDraftMessages = (newMessages, persistedMessages, requestData
|
|
|
453
453
|
if (!prefixRef) return null
|
|
454
454
|
|
|
455
455
|
const draftMessageTargetPrefix = cds.odata.urlify(
|
|
456
|
-
{ SELECT: { from: { ref: prefixRef } } },
|
|
456
|
+
{ query: { SELECT: { from: { ref: prefixRef } } }, subject: { ref: prefixRef } },
|
|
457
457
|
{ kind: 'odata-v4', model: txModel }
|
|
458
458
|
).path
|
|
459
459
|
|
|
@@ -483,7 +483,7 @@ const compileUpdatedDraftMessages = (newMessages, persistedMessages, requestData
|
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
message.prefix = cds.odata.urlify(
|
|
486
|
-
{ SELECT: { from: { ref: messagePrefixRef } } },
|
|
486
|
+
{ query: { SELECT: { from: { ref: messagePrefixRef } } }, subject: { ref: messagePrefixRef } },
|
|
487
487
|
{ kind: 'odata-v4', model: txModel }
|
|
488
488
|
).path
|
|
489
489
|
|
|
@@ -1437,11 +1437,11 @@ const Read = {
|
|
|
1437
1437
|
|
|
1438
1438
|
// TODO: This seems excessive ... how to compare more efficiently?
|
|
1439
1439
|
const queryPrefixUrl = cds.odata.urlify(
|
|
1440
|
-
{ SELECT: { from: { ref: queryPrefixRef } } },
|
|
1440
|
+
{ query: { SELECT: { from: { ref: queryPrefixRef } } }, subject: { ref: queryPrefixRef } },
|
|
1441
1441
|
{ kind: 'odata-v4', model: txModel }
|
|
1442
1442
|
).path
|
|
1443
1443
|
const msgPrefixUrl = cds.odata.urlify(
|
|
1444
|
-
{ SELECT: { from: { ref: msgPrefixRef } } },
|
|
1444
|
+
{ query: { SELECT: { from: { ref: msgPrefixRef } } }, subject: { ref: msgPrefixRef } },
|
|
1445
1445
|
{ kind: 'odata-v4', model: txModel }
|
|
1446
1446
|
).path
|
|
1447
1447
|
|
|
@@ -2443,7 +2443,7 @@ async function onCancel(req, next) {
|
|
|
2443
2443
|
|
|
2444
2444
|
const prefixRef = _extractPrefixRef(req.query.DELETE.from.ref, queryRootEntity)
|
|
2445
2445
|
const messageTargetPrefix = cds.odata.urlify(
|
|
2446
|
-
{ SELECT: { from: { ref: prefixRef } } },
|
|
2446
|
+
{ query: { SELECT: { from: { ref: prefixRef } } }, subject: { ref: prefixRef } },
|
|
2447
2447
|
{ kind: 'odata-v4', model: req.context.tx.model }
|
|
2448
2448
|
).path
|
|
2449
2449
|
|
|
@@ -2570,6 +2570,7 @@ const _readAfterDraftAction = async function ({ req, payload, action }) {
|
|
|
2570
2570
|
}
|
|
2571
2571
|
}
|
|
2572
2572
|
|
|
2573
|
+
// prettier-ignore
|
|
2573
2574
|
module.exports = cds.service.impl(function () {
|
|
2574
2575
|
if (!this.entities?.DraftAdministrativeData) return
|
|
2575
2576
|
|
|
@@ -2577,14 +2578,17 @@ module.exports = cds.service.impl(function () {
|
|
|
2577
2578
|
Object.defineProperty(this, '_datasource', { value: cds.db })
|
|
2578
2579
|
|
|
2579
2580
|
// Extend the AppService's API by draft specific functions
|
|
2580
|
-
this.new = (draft, key)
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
this.
|
|
2581
|
+
this.new = function (draft, key) {
|
|
2582
|
+
return {
|
|
2583
|
+
then: (r, e) => this.send('NEW', draft, key).then(r, e),
|
|
2584
|
+
for: key => this.send('EDIT', typeof draft === 'string' ? draft.replace(/\.drafts$/, '') : draft.actives, key)
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
this.edit = function (active, key) { return this.send('EDIT', active, key) }
|
|
2589
|
+
this.save = function (draft, key) { return this.send('SAVE', draft, key) }
|
|
2590
|
+
this.cancel = function (draft, key) { return this.send('CANCEL', draft, key) }
|
|
2591
|
+
this.discard = function (draft, key) { return this.send('DISCARD', draft, key) }
|
|
2588
2592
|
|
|
2589
2593
|
// Override the AppService's handle function
|
|
2590
2594
|
this.handle = !cds.env.features.legacy_srv_results
|
|
@@ -2596,9 +2600,13 @@ module.exports = cds.service.impl(function () {
|
|
|
2596
2600
|
return Array.isArray(res) && 'affected' in res ? req.data : res
|
|
2597
2601
|
}
|
|
2598
2602
|
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
this.on('
|
|
2603
|
+
// NOTE: These handler registrations MUST use inline functions
|
|
2604
|
+
// NOTE: > Arrow functions or functions bound with `.bind` will
|
|
2605
|
+
// NOTE: > ... not be able to access the context tx from `this`
|
|
2606
|
+
this.on('NEW', '*', function (req, next) { return onNew.call(this, req, next) })
|
|
2607
|
+
this.on('EDIT', '*', function (req, next) { return onEdit.call(this, req, next) })
|
|
2608
|
+
this.on('CANCEL', '*', function (req, next) { return onCancel.call(this, req, next) })
|
|
2609
|
+
this.on('draftPrepare', '*', function (req, next) { return onPrepare.call(this, req, next) })
|
|
2603
2610
|
})
|
|
2611
|
+
|
|
2604
2612
|
module.exports.compileUpdatedDraftMessages = compileUpdatedDraftMessages
|
|
@@ -20,16 +20,18 @@ class EndpointRegistry {
|
|
|
20
20
|
this.webhookCallbacks = new Map()
|
|
21
21
|
this.deployCallbacks = new Map()
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const _HAS_APP_AUTH = !!(
|
|
24
24
|
cds.env.requires.auth &&
|
|
25
25
|
(cds.env.requires.auth.impl || !(cds.env.requires.auth.kind in { mocked: 1, 'mocked-auth': 1 }))
|
|
26
26
|
)
|
|
27
|
+
const _HAS_MESSAGING_XSUAA = !!cds.env.requires.messaging?.xsuaa
|
|
28
|
+
const _IS_SECURED = _HAS_APP_AUTH || _HAS_MESSAGING_XSUAA
|
|
27
29
|
const _IS_PRODUCTION = process.env.NODE_ENV === 'production'
|
|
28
30
|
|
|
29
31
|
cds.app.use(basePath, cds.middlewares.context())
|
|
30
32
|
if (_IS_SECURED) {
|
|
31
33
|
// unofficial XSUAA fallback
|
|
32
|
-
if (
|
|
34
|
+
if (_HAS_MESSAGING_XSUAA) {
|
|
33
35
|
cds.app.use(basePath, _xsuaa_fallback())
|
|
34
36
|
} else {
|
|
35
37
|
cds.app.use(basePath, cds.middlewares.auth())
|
|
@@ -38,7 +40,11 @@ class EndpointRegistry {
|
|
|
38
40
|
cds.app.use(basePath, (_req, _res, next) => {
|
|
39
41
|
next(cds.context.user._is_anonymous ? 401 : undefined)
|
|
40
42
|
})
|
|
41
|
-
} else if (_IS_PRODUCTION)
|
|
43
|
+
} else if (_IS_PRODUCTION) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
'Messaging endpoints require authentication in production. Configure cds.requires.auth or cds.requires.messaging.xsuaa.'
|
|
46
|
+
)
|
|
47
|
+
}
|
|
42
48
|
|
|
43
49
|
cds.app.use(basePath, express.json({ type: 'application/*+json' }))
|
|
44
50
|
cds.app.use(basePath, express.json())
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
const cds = require('../cds')
|
|
2
|
-
const {
|
|
3
|
-
getCloudSdk,
|
|
4
|
-
getCloudSdkConnectivity,
|
|
5
|
-
getCloudSdkResilience,
|
|
6
|
-
shouldUseCloudSdk
|
|
7
|
-
} = require('./utils/cloudSdkProvider')
|
|
2
|
+
const { getCloudSdk, getCloudSdkResilience, shouldUseCloudSdk } = require('./utils/cloudSdkProvider')
|
|
8
3
|
const { run } = require('./utils/client')
|
|
9
4
|
const { extractRequestConfig } = require('./utils/query')
|
|
10
5
|
const { hasAliasedColumns } = require('./utils/data')
|
|
@@ -171,13 +166,6 @@ const _isSelectWithAliasedColumns = q => q?.SELECT && !q._transitions && q.SELEC
|
|
|
171
166
|
|
|
172
167
|
const resolvedTargetOfQuery = q => q?._transitions?.at(-1)?.target
|
|
173
168
|
|
|
174
|
-
const _resolveSelectionStrategy = selectionStrategy => {
|
|
175
|
-
const { DestinationSelectionStrategies } = getCloudSdkConnectivity()
|
|
176
|
-
const strategy = DestinationSelectionStrategies[selectionStrategy]
|
|
177
|
-
if (typeof strategy !== 'function') cds.error`Unsupported destination selection strategy "${selectionStrategy}".`
|
|
178
|
-
return strategy
|
|
179
|
-
}
|
|
180
|
-
|
|
181
169
|
const _getKind = options => {
|
|
182
170
|
let kind = options.credentials?.kind ?? options.kind
|
|
183
171
|
if (typeof kind === 'object') {
|
|
@@ -206,9 +194,6 @@ class RemoteService extends cds.Service {
|
|
|
206
194
|
this.datasource = this.options.datasource
|
|
207
195
|
|
|
208
196
|
this.destinationOptions = this.options.destinationOptions || {}
|
|
209
|
-
if (typeof this.destinationOptions.selectionStrategy === 'string') {
|
|
210
|
-
this.destinationOptions.selectionStrategy = _resolveSelectionStrategy(this.destinationOptions.selectionStrategy)
|
|
211
|
-
}
|
|
212
197
|
|
|
213
198
|
if (this.options.credentials.destination) this.destination = this.options.credentials.destination
|
|
214
199
|
else this.destination = _getDestination(this.definition?.name ?? this.datasource, this.options.credentials)
|
|
@@ -223,7 +208,7 @@ class RemoteService extends cds.Service {
|
|
|
223
208
|
|
|
224
209
|
// This is required for BAS creating remote services only for events
|
|
225
210
|
// Middlewares are created at time of the first request, on the fly
|
|
226
|
-
if (shouldUseCloudSdk(
|
|
211
|
+
if (shouldUseCloudSdk()) {
|
|
227
212
|
this.middlewares = {
|
|
228
213
|
timeout: getCloudSdkResilience().timeout(this.requestTimeout),
|
|
229
214
|
csrf: this.csrf && getCloudSdk().csrf(this.csrf)
|
|
@@ -249,7 +234,7 @@ class RemoteService extends cds.Service {
|
|
|
249
234
|
if (typeof this.destination === 'object' && !this.destination.url)
|
|
250
235
|
cds.error`"url" or "destination" property must be configured in "credentials" of "${this.name}".`
|
|
251
236
|
|
|
252
|
-
const requestConfig = extractRequestConfig(req,
|
|
237
|
+
const requestConfig = extractRequestConfig(req, this)
|
|
253
238
|
requestConfig.headers = _getHeaders(requestConfig.headers, req)
|
|
254
239
|
|
|
255
240
|
if (this.kind === 'hcql' && req.iterator && !req.objectMode)
|
|
@@ -284,7 +269,7 @@ class RemoteService extends cds.Service {
|
|
|
284
269
|
if (jwt) additionalOptions.jwt = jwt
|
|
285
270
|
|
|
286
271
|
const csrfConfig = requestConfig._autoBatchedGet ? this.csrfInBatch : this.csrf
|
|
287
|
-
if (shouldUseCloudSdk(
|
|
272
|
+
if (shouldUseCloudSdk()) {
|
|
288
273
|
// Mount resilience and csrf middlewares for SAP Cloud SDK
|
|
289
274
|
requestConfig.middleware = [this.middlewares.timeout]
|
|
290
275
|
if (csrfConfig && this.middlewares.csrf) requestConfig.middleware.push(this.middlewares.csrf)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LRU cache backed by Map insertion order.
|
|
3
|
+
* On get/set the entry is moved to the MRU end; the LRU entry (first key) is
|
|
4
|
+
* evicted when the map is full. `maxSize = 0` means unlimited.
|
|
5
|
+
*/
|
|
6
|
+
class LruCache {
|
|
7
|
+
/** @param {number} [maxSize=0] Maximum number of entries; 0 = unlimited. */
|
|
8
|
+
constructor(maxSize = 0) {
|
|
9
|
+
this._map = new Map()
|
|
10
|
+
this._maxSize = maxSize
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @param {*} key Cache key. */
|
|
14
|
+
get(key) {
|
|
15
|
+
const value = this._map.get(key)
|
|
16
|
+
if (value !== undefined) {
|
|
17
|
+
this._map.delete(key)
|
|
18
|
+
this._map.set(key, value)
|
|
19
|
+
}
|
|
20
|
+
return value
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {*} key Cache key. `null` and `undefined` are ignored.
|
|
25
|
+
* @param {*} value Value to store.
|
|
26
|
+
* @param {number} [ttl] Time-to-live in milliseconds. Entry is auto-deleted after this duration.
|
|
27
|
+
*/
|
|
28
|
+
set(key, value, ttl) {
|
|
29
|
+
if (key == null) return
|
|
30
|
+
this._map.delete(key)
|
|
31
|
+
if (this._maxSize > 0 && this._map.size >= this._maxSize) this._map.delete(this._map.keys().next().value)
|
|
32
|
+
this._map.set(key, value)
|
|
33
|
+
if (ttl > 0) setTimeout(() => this._map.delete(key), ttl).unref()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** @param {*} key Cache key. */
|
|
37
|
+
delete(key) {
|
|
38
|
+
this._map.delete(key)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { LruCache }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const cds = require('../../cds')
|
|
2
2
|
const LOG = cds.log('remote')
|
|
3
3
|
|
|
4
|
-
const { getCloudSdk, shouldUseCloudSdk } = require('./cloudSdkProvider')
|
|
4
|
+
const { getCloudSdk, getCloudSdkConnectivity, shouldUseCloudSdk } = require('./cloudSdkProvider')
|
|
5
5
|
const { executeHttpRequest: fetchExecuteHttpRequest } = require('./fetchClient')
|
|
6
6
|
|
|
7
7
|
const SANITIZE_VALUES = process.env.NODE_ENV === 'production' && cds.env.log.sanitize_values !== false
|
|
@@ -27,7 +27,6 @@ const _sanitizeHeaders = headers => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const _executeHttpRequest = async ({ requestConfig, destination, destinationOptions, jwt }) => {
|
|
30
|
-
const useCloudSdk = shouldUseCloudSdk(destination)
|
|
31
30
|
if (typeof destination === 'string') {
|
|
32
31
|
destination = { destinationName: destination, ...destinationOptions }
|
|
33
32
|
if (destination.jwt === undefined) destination.jwt = jwt
|
|
@@ -48,7 +47,7 @@ const _executeHttpRequest = async ({ requestConfig, destination, destinationOpti
|
|
|
48
47
|
const maxBodyLength = cds.env?.remote?.max_body_length
|
|
49
48
|
if (maxBodyLength) requestConfig.maxBodyLength = maxBodyLength
|
|
50
49
|
|
|
51
|
-
if (
|
|
50
|
+
if (shouldUseCloudSdk()) {
|
|
52
51
|
const { executeHttpRequestWithOrigin } = getCloudSdk()
|
|
53
52
|
// cloud sdk requires a new mechanism to differentiate the priority of headers
|
|
54
53
|
// "custom" keeps the highest priority as before
|
|
@@ -56,6 +55,15 @@ const _executeHttpRequest = async ({ requestConfig, destination, destinationOpti
|
|
|
56
55
|
...requestConfig,
|
|
57
56
|
headers: { custom: { ...requestConfig.headers } }
|
|
58
57
|
}
|
|
58
|
+
// selectionStrategy is kept as a plain string in destinationOptions;
|
|
59
|
+
// Cloud SDK needs the corresponding function — resolve it lazily here
|
|
60
|
+
if (typeof destination.selectionStrategy === 'string') {
|
|
61
|
+
const { DestinationSelectionStrategies } = getCloudSdkConnectivity()
|
|
62
|
+
const strategy = DestinationSelectionStrategies[destination.selectionStrategy]
|
|
63
|
+
if (typeof strategy !== 'function')
|
|
64
|
+
cds.error`Unsupported destination selection strategy "${destination.selectionStrategy}".`
|
|
65
|
+
destination = { ...destination, selectionStrategy: strategy }
|
|
66
|
+
}
|
|
59
67
|
if (LOG._debug) LOG.debug('Executing via @sap-cloud-sdk/http-client.')
|
|
60
68
|
return executeHttpRequestWithOrigin(destination, sdkConfig, { fetchCsrfToken: false })
|
|
61
69
|
}
|
|
@@ -270,8 +278,10 @@ module.exports.run = async (requestConfig, options) => {
|
|
|
270
278
|
|
|
271
279
|
if (kind === 'hcql') {
|
|
272
280
|
if (response.headers?.['content-type']?.includes('application/octet-stream')) return response.data
|
|
273
|
-
let { data = [], affected } = response.data
|
|
281
|
+
let { data = [], affected, $count } = response.data
|
|
274
282
|
if (affected !== undefined) data.affected = affected
|
|
283
|
+
if ($count == null && response.headers['x-total-count']) $count = Number(response.headers['x-total-count'])
|
|
284
|
+
if ($count !== undefined) data.$count = $count
|
|
275
285
|
return data
|
|
276
286
|
}
|
|
277
287
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const cds = require('../../cds')
|
|
2
|
-
const { findLocalDestinations } = require('./fetchClient')
|
|
3
2
|
|
|
4
3
|
const _require = module => {
|
|
5
4
|
try {
|
|
@@ -39,14 +38,8 @@ const isCloudSdkInstalled = () => {
|
|
|
39
38
|
return _cloudSdkInstalled
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
const shouldUseCloudSdk =
|
|
43
|
-
//
|
|
44
|
-
const _destination = typeof destination === 'string' ? findLocalDestinations(destination)[0] : destination
|
|
45
|
-
if (!_destination?.url) return true
|
|
46
|
-
if (_destination.authentication && !(_destination.authentication in { NoAuthentication: 1, BasicAuthentication: 1 }))
|
|
47
|
-
return true
|
|
48
|
-
// here, it would be _possible_ to use native fetch
|
|
49
|
-
// explicit config?
|
|
41
|
+
const shouldUseCloudSdk = () => {
|
|
42
|
+
// Explicit config takes priority
|
|
50
43
|
if (cds.env.remote?.native_fetch != null) return !cds.env.remote.native_fetch
|
|
51
44
|
// if cloud sdk is there, use it
|
|
52
45
|
return isCloudSdkInstalled()
|