@sap/cds-dk 10.0.7 → 10.1.1
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 +106 -0
- package/bin/add.js +7 -23
- package/bin/bind.js +14 -0
- package/bin/build.js +21 -34
- package/bin/cds.js +1 -1
- package/bin/compile/index.js +16 -41
- package/bin/completion/completionFs.js +11 -8
- package/bin/completion/index.js +603 -80
- package/bin/completion/scripts/cds.fish +620 -0
- package/bin/completion/scripts/cds.ps1 +403 -0
- package/bin/completion/scripts/cds.sh +327 -0
- package/bin/completion/scripts/cds.zsh +296 -0
- package/bin/completion/templates/cds-tmpl.fish +65 -0
- package/bin/completion/templates/cds-tmpl.ps1 +217 -0
- package/bin/completion/templates/cds-tmpl.sh +93 -0
- package/bin/completion/templates/cds-tmpl.zsh +74 -0
- package/bin/deploy/index.js +11 -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/env.js +4 -1
- package/bin/export.js +44 -6
- package/bin/help/export.md +3 -0
- package/bin/help.js +1 -5
- package/bin/import.js +9 -0
- package/bin/init.js +6 -24
- package/bin/inspect.js +8 -0
- package/bin/lint.js +5 -3
- package/bin/login.js +26 -20
- package/bin/minify.js +6 -1
- package/bin/pull.js +19 -6
- package/bin/push.js +19 -6
- package/bin/repl.js +11 -2
- package/bin/run.js +12 -1
- package/bin/serve.js +13 -2
- package/bin/up.js +17 -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 +10 -4
- package/bin/version.js +10 -1
- package/{lib → bin}/watch/hot-reload.js +1 -1
- package/bin/{watch.js → watch/index.js} +24 -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/build/util.js +2 -4
- 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 +117 -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/@cap-js/db-service/CHANGELOG.md +17 -0
- package/node_modules/@cap-js/db-service/lib/common/generic-pool.js +4 -7
- package/node_modules/@cap-js/db-service/lib/cqn2pql.js +1 -1
- package/node_modules/@cap-js/db-service/lib/cqn2sql.js +15 -11
- package/node_modules/@cap-js/db-service/lib/cqn4sql.js +119 -19
- package/node_modules/@cap-js/db-service/lib/infer/index.js +27 -16
- package/node_modules/@cap-js/db-service/lib/recursion-guard.js +40 -0
- package/node_modules/@cap-js/db-service/lib/search.js +1 -1
- package/node_modules/@cap-js/db-service/package.json +1 -1
- package/node_modules/@cap-js/sqlite/CHANGELOG.md +19 -0
- package/node_modules/@cap-js/sqlite/lib/SQLiteService.js +110 -14
- package/node_modules/@cap-js/sqlite/package.json +3 -3
- 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 +75 -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 +48 -18
- 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 +4 -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 +15 -0
- package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +10 -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/db/flattening.js +4 -3
- package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +40 -0
- package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +17 -1
- package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +20 -0
- package/node_modules/@sap/cds-compiler/lib/transform/fioriTreeViews.js +12 -1
- package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +7 -2
- package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +11 -5
- package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +48 -10
- package/node_modules/@sap/cds-compiler/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/CHANGELOG.md +49 -0
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +26 -5
- package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +37 -16
- package/node_modules/@sap/cds-mtxs/lib/utils.js +23 -7
- package/node_modules/@sap/cds-mtxs/package.json +1 -1
- package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +63 -8
- package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.js +23 -3
- package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +15 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/annotations.js +2 -2
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +2 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +2 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +45 -0
- package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +30 -16
- package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +49 -10
- package/node_modules/@sap/cds-mtxs/srv/model-provider.js +28 -4
- package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +19 -12
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +1 -1
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +6 -3
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +271 -0
- package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +7 -10
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +212 -0
- package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +61 -0
- 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 +2 -2
- 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
- /package/node_modules/@sap/cds-mtxs/srv/worker/{pool.js → model-worker-pool.js} +0 -0
- /package/node_modules/@sap/cds-mtxs/srv/worker/{load.js → model-worker.js} +0 -0
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {object} FunctionRendererContext
|
|
5
|
+
* @property {Function} renderArgs - Renders a function argument node to SQL string.
|
|
6
|
+
* @property {Function} error - Compiler error reporting function.
|
|
7
|
+
* @property {string[]} path - Current CSN path for error reporting.
|
|
8
|
+
* @property {{ embeddingDefaultModel: string, embeddingHanaDefaultRemoteSource: string }} vector - Vector embedding options.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {(this: FunctionRendererContext, signature: object) => string} DbFunction
|
|
13
|
+
*/
|
|
14
|
+
|
|
3
15
|
/**
|
|
4
16
|
* List of functions for which we provide a mapping to the respective SQL dialect.
|
|
5
17
|
* All functions are lowercase, the caller may treat the function name case-insensitive.
|
|
6
18
|
*
|
|
7
19
|
* The `this` context within the functions hold the `renderArgs` function.
|
|
8
20
|
*/
|
|
21
|
+
/** @type {Record<string, Record<string, DbFunction>>} */
|
|
9
22
|
const oDataFunctions = {
|
|
10
23
|
// https://www.sqlite.org/lang_corefunc.html
|
|
11
24
|
sqlite: {
|
|
@@ -116,7 +129,7 @@ const oDataFunctions = {
|
|
|
116
129
|
// let x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
117
130
|
// const isNegative = x.startsWith("'-"); // Check for leading '-'
|
|
118
131
|
// x = isNegative ? x.replace('-', '') : x; // remove for easier processing
|
|
119
|
-
// const sql = `((cast(substr(${x},2,instr(${x},'DT') - 2) as Integer) + (julianday('-4713-11-25T' || replace(replace(replace(substr(${x},instr(${x},'DT') + 2),'H',':'),'M',':'),'S','Z')) - 0.5)) * 86400)`;
|
|
132
|
+
// const sql = `((cast(substr(${ x },2,instr(${ x },'DT') - 2) as Integer) + (julianday('-4713-11-25T' || replace(replace(replace(substr(${ x },instr(${ x },'DT') + 2),'H',':'),'M',':'),'S','Z')) - 0.5)) * 86400)`;
|
|
120
133
|
// return isNegative ? `-(${sql})` : sql;
|
|
121
134
|
// },
|
|
122
135
|
},
|
|
@@ -260,7 +273,7 @@ const oDataFunctions = {
|
|
|
260
273
|
},
|
|
261
274
|
matchespattern(signature) {
|
|
262
275
|
// case … when only works as column expression (not in where)
|
|
263
|
-
// in the where clause, only "${x} LIKE_REGEXPR ${y}" works
|
|
276
|
+
// in the where clause, only "${ x } LIKE_REGEXPR ${ y }" works
|
|
264
277
|
const args = getArgs(signature);
|
|
265
278
|
checkArgs.call(this, 'matchespattern', args, 2);
|
|
266
279
|
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
@@ -556,6 +569,7 @@ const oDataFunctions = {
|
|
|
556
569
|
},
|
|
557
570
|
};
|
|
558
571
|
|
|
572
|
+
/** @type {Record<string, Record<string, DbFunction>>} */
|
|
559
573
|
const hanaFunctions = {
|
|
560
574
|
sqlite: {
|
|
561
575
|
/**
|
|
@@ -659,6 +673,11 @@ const hanaFunctions = {
|
|
|
659
673
|
checkArgs.call(this, 'years_between', args, 2);
|
|
660
674
|
return `floor((${ hanaFunctions.sqlite.months_between.call(this, signature) }) / 12)`;
|
|
661
675
|
},
|
|
676
|
+
|
|
677
|
+
//
|
|
678
|
+
// Note: Vector functions for SQLite (cosine_similarity, l2distance, l2normalize and vector_embedding) have the
|
|
679
|
+
// same parameters as on HANA because we provide them via UDFs
|
|
680
|
+
//
|
|
662
681
|
},
|
|
663
682
|
postgres: {
|
|
664
683
|
nano100_between(signature) {
|
|
@@ -697,6 +716,33 @@ const hanaFunctions = {
|
|
|
697
716
|
checkArgs.call(this, 'years_between', args, 2);
|
|
698
717
|
return `floor((${ hanaFunctions.postgres.months_between.call(this, signature) }) / 12)::INTEGER`;
|
|
699
718
|
},
|
|
719
|
+
|
|
720
|
+
//
|
|
721
|
+
// Vector functions for postgres vector support based on the https://github.com/pgvector/pgvector
|
|
722
|
+
//
|
|
723
|
+
cosine_similarity(signature) {
|
|
724
|
+
const args = getArgs(signature);
|
|
725
|
+
checkArgs.call(this, 'cosine_similarity', args, 2);
|
|
726
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
727
|
+
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
728
|
+
|
|
729
|
+
return `1 - cosine_distance(${ x },${ y })`;
|
|
730
|
+
},
|
|
731
|
+
l2distance(signature) {
|
|
732
|
+
const args = getArgs(signature);
|
|
733
|
+
checkArgs.call(this, 'l2distance', args, 2);
|
|
734
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
735
|
+
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
736
|
+
|
|
737
|
+
return `l2_distance(${ x },${ y })`;
|
|
738
|
+
},
|
|
739
|
+
l2normalize(signature) {
|
|
740
|
+
const args = getArgs(signature);
|
|
741
|
+
checkArgs.call(this, 'l2normalize', args, 1);
|
|
742
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
743
|
+
|
|
744
|
+
return `l2_normalize(${ x })`;
|
|
745
|
+
},
|
|
700
746
|
},
|
|
701
747
|
h2: {
|
|
702
748
|
nano100_between(signature) {
|
|
@@ -757,8 +803,18 @@ const hanaFunctions = {
|
|
|
757
803
|
checkArgs.call(this, 'years_between', args, 2);
|
|
758
804
|
return `floor((${ hanaFunctions.h2.months_between.call(this, signature) }) / 12)`;
|
|
759
805
|
},
|
|
806
|
+
|
|
807
|
+
//
|
|
808
|
+
// Note: Vector functions for H2 (cosine_similarity, l2distance, l2normalize, and vector_embedding) have the
|
|
809
|
+
// same parameters as on HANA because we provide them via UDFs
|
|
810
|
+
//
|
|
811
|
+
},
|
|
812
|
+
common: {
|
|
813
|
+
vector_embedding(signature) {
|
|
814
|
+
/** @type {FunctionRendererContext} */ const ctx = /** @type {any} */ (this);
|
|
815
|
+
return vectorEmbedding.call(ctx, signature);
|
|
816
|
+
},
|
|
760
817
|
},
|
|
761
|
-
common: {},
|
|
762
818
|
// identity functions + argument check
|
|
763
819
|
hana: {
|
|
764
820
|
nano100_between(signature) {
|
|
@@ -797,8 +853,67 @@ const hanaFunctions = {
|
|
|
797
853
|
checkArgs.call(this, 'years_between', args, 2);
|
|
798
854
|
return `years_between(${ this.renderArgs({ ...signature, args }) })`;
|
|
799
855
|
},
|
|
856
|
+
|
|
857
|
+
//
|
|
858
|
+
// Vector functions - only identity check
|
|
859
|
+
//
|
|
860
|
+
cosine_similarity(signature) {
|
|
861
|
+
const args = getArgs(signature);
|
|
862
|
+
checkArgs.call(this, 'cosine_similarity', args, 2);
|
|
863
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
864
|
+
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
865
|
+
|
|
866
|
+
return `cosine_similarity(${ x },${ y })`;
|
|
867
|
+
},
|
|
868
|
+
l2distance(signature) {
|
|
869
|
+
const args = getArgs(signature);
|
|
870
|
+
checkArgs.call(this, 'l2distance', args, 2);
|
|
871
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
872
|
+
const y = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
873
|
+
|
|
874
|
+
return `l2distance(${ x },${ y })`;
|
|
875
|
+
},
|
|
876
|
+
l2normalize(signature) {
|
|
877
|
+
const args = getArgs(signature);
|
|
878
|
+
checkArgs.call(this, 'l2normalize', args, 1);
|
|
879
|
+
const x = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
880
|
+
|
|
881
|
+
return `l2normalize(${ x })`;
|
|
882
|
+
},
|
|
883
|
+
vector_embedding(signature) {
|
|
884
|
+
/** @type {FunctionRendererContext} */ const ctx = /** @type {any} */ (this);
|
|
885
|
+
const sql = vectorEmbedding.call(ctx, signature);
|
|
886
|
+
if (sql.match('SAP.'))
|
|
887
|
+
return sql;
|
|
888
|
+
// If the model does not start with SAP an additional fourth parameter
|
|
889
|
+
// is necessary specifying the remote source behind which SAP AI Core lies on HANA
|
|
890
|
+
return `${ sql.substring(0, sql.length - 1) }, ${ this.vector.embeddingHanaDefaultRemoteSource })`;
|
|
891
|
+
},
|
|
800
892
|
},
|
|
801
893
|
};
|
|
894
|
+
/**
|
|
895
|
+
* Arguments:
|
|
896
|
+
* 1. (mandatory) property for which to generate a vector
|
|
897
|
+
* 2. (optional) DOCUMENT / QUERY kind for embedding function. If not provided we default to 'DOCUMENT'
|
|
898
|
+
* 3. (optional) model. If not provided we default to a compiler setting or else the SAP NXY model
|
|
899
|
+
* @this {FunctionRendererContext}
|
|
900
|
+
* @param {object} signature
|
|
901
|
+
* @returns {string}
|
|
902
|
+
*/
|
|
903
|
+
function vectorEmbedding( signature ) {
|
|
904
|
+
const args = getArgs(signature);
|
|
905
|
+
// Default to kind DOCUMENT if no kind is specified
|
|
906
|
+
if (args.length === 1)
|
|
907
|
+
args.push('DOCUMENT');
|
|
908
|
+
// Default to the compiler option vectorEmbeddingDefaultModel if no model is specified
|
|
909
|
+
if (args.length === 2)
|
|
910
|
+
args.push(this.vector.embeddingDefaultModel);
|
|
911
|
+
checkArgs.call(this, 'vector_embedding', args, 3);
|
|
912
|
+
const field = this.renderArgs({ ...signature, args: [ args[0] ] });
|
|
913
|
+
const kind = this.renderArgs({ ...signature, args: [ args[1] ] });
|
|
914
|
+
const model = this.renderArgs({ ...signature, args: [ args[2] ] });
|
|
915
|
+
return `vector_embedding(${ field }, ${ kind }, ${ model })`;
|
|
916
|
+
}
|
|
802
917
|
|
|
803
918
|
/**
|
|
804
919
|
* Normalizes `signature.args` to a positional array, handling both
|
|
@@ -808,6 +923,13 @@ function getArgs( signature ) {
|
|
|
808
923
|
return Array.isArray(signature.args) ? signature.args : Object.values(signature.args);
|
|
809
924
|
}
|
|
810
925
|
|
|
926
|
+
/**
|
|
927
|
+
* @this {FunctionRendererContext}
|
|
928
|
+
* @param {string} funcName
|
|
929
|
+
* @param {any[]} receivedArgs
|
|
930
|
+
* @param {number} expectedLength
|
|
931
|
+
* @param {number | null} alternativeLength
|
|
932
|
+
*/
|
|
811
933
|
function checkArgs( funcName, receivedArgs, expectedLength, alternativeLength = null ) {
|
|
812
934
|
const expectedMismatch = receivedArgs.length < expectedLength;
|
|
813
935
|
const alternativeMismatch
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
const msg = require('../base/messages');
|
|
17
17
|
const { CompilerAssertion } = require('../base/error');
|
|
18
|
+
const { isLeadingQuery } = require('../compiler/utils');
|
|
18
19
|
|
|
19
20
|
const $inferred = Symbol.for('cds.$inferred');
|
|
20
21
|
const $location = Symbol.for('cds.$location');
|
|
@@ -206,7 +207,7 @@ function revealInternalProperties( model, nameOrPath ) {
|
|
|
206
207
|
|
|
207
208
|
function elements( dict, parent ) {
|
|
208
209
|
// do not display elements of leading query as they are the same as the view elements:
|
|
209
|
-
return (
|
|
210
|
+
return (isLeadingQuery( parent ))
|
|
210
211
|
? '{ ... }'
|
|
211
212
|
: dictionary( dict );
|
|
212
213
|
}
|
|
@@ -41,6 +41,7 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
|
|
|
41
41
|
mixin: dictionary,
|
|
42
42
|
ref: pathRef,
|
|
43
43
|
$origin: () => {}, // no-op
|
|
44
|
+
$backlink: () => undefined,
|
|
44
45
|
'@': annotation,
|
|
45
46
|
};
|
|
46
47
|
|
|
@@ -68,6 +69,8 @@ function applyTransformationsInternal( parent, prop, customTransformers, artifac
|
|
|
68
69
|
* @param {object} node The value of node[_prop]
|
|
69
70
|
*/
|
|
70
71
|
function standard( _parent, _prop, node ) {
|
|
72
|
+
if (_prop === '$backlink') // above line in transformers doesn't seem to help...
|
|
73
|
+
return; // ...in the OData backend
|
|
71
74
|
if (!node || typeof node !== 'object' ||
|
|
72
75
|
!{}.propertyIsEnumerable.call( _parent, _prop ) ||
|
|
73
76
|
(options.skipIgnore && node.$ignore) ||
|
|
@@ -420,6 +423,17 @@ function mergeTransformers( transformers, that ) {
|
|
|
420
423
|
return remapped;
|
|
421
424
|
}
|
|
422
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Return true if the annotation expression ref node is a simple reference:
|
|
428
|
+
* all ref steps are plain strings, and the node has neither `param` nor `cast`.
|
|
429
|
+
*
|
|
430
|
+
* @param {object} annotation An annotation expression node (has `ref`, optionally `param`, `cast`)
|
|
431
|
+
* @returns {boolean}
|
|
432
|
+
*/
|
|
433
|
+
function isSimpleAnnoExprRef(annotation) {
|
|
434
|
+
return annotation.ref && annotation.ref.every(s => typeof s === 'string') && !annotation.param && !annotation.cast;
|
|
435
|
+
}
|
|
436
|
+
|
|
423
437
|
module.exports = {
|
|
424
438
|
mergeTransformers,
|
|
425
439
|
transformExpression,
|
|
@@ -427,6 +441,7 @@ module.exports = {
|
|
|
427
441
|
applyTransformations,
|
|
428
442
|
applyTransformationsOnNonDictionary,
|
|
429
443
|
applyTransformationsOnDictionary,
|
|
444
|
+
isSimpleAnnoExprRef,
|
|
430
445
|
};
|
|
431
446
|
|
|
432
447
|
|
|
@@ -5,6 +5,7 @@ const {
|
|
|
5
5
|
applyTransformationsOnNonDictionary,
|
|
6
6
|
applyTransformations,
|
|
7
7
|
implicitAs,
|
|
8
|
+
isSimpleAnnoExprRef,
|
|
8
9
|
} = require('../../model/csnUtils');
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -136,7 +137,9 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
|
|
|
136
137
|
if (obj[anno].ref)
|
|
137
138
|
transformer.ref(obj[anno], 'ref', obj[anno].ref, path.concat(anno));
|
|
138
139
|
const annoAfter = JSON.stringify(obj[anno]);
|
|
139
|
-
if (annoBefore !== annoAfter &&
|
|
140
|
+
if (annoBefore !== annoAfter &&
|
|
141
|
+
(options.transformation !== 'effective' || obj[anno]['=']) &&
|
|
142
|
+
!(obj[anno].ref && isSimpleAnnoExprRef(obj[anno])))
|
|
140
143
|
obj[anno]['='] = true;
|
|
141
144
|
});
|
|
142
145
|
}
|
|
@@ -219,7 +222,7 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
|
|
|
219
222
|
*/
|
|
220
223
|
function getTransformer() {
|
|
221
224
|
return {
|
|
222
|
-
ref: (refOwner, prop, ref, path, grandParent) => {
|
|
225
|
+
ref: (refOwner, prop, ref, path, grandParent, _opt, ctx) => {
|
|
223
226
|
// [<assoc base>.]<managed assoc>.<field>
|
|
224
227
|
if (ref.length > 1) {
|
|
225
228
|
const { links } = inspectRef(path);
|
|
@@ -249,6 +252,11 @@ function getFKAccessFinalizer( csn, options, csnUtils, pathDelimiter, processOnI
|
|
|
249
252
|
else {
|
|
250
253
|
refOwner.ref = [ ...ref.slice(0, i), newFkName ];
|
|
251
254
|
}
|
|
255
|
+
if (ctx?.annoExpr === refOwner) {
|
|
256
|
+
ctx.annoExpr['='] = isSimpleAnnoExprRef(refOwner)
|
|
257
|
+
? refOwner.ref.join('.')
|
|
258
|
+
: true;
|
|
259
|
+
}
|
|
252
260
|
}
|
|
253
261
|
}
|
|
254
262
|
else {
|
|
@@ -175,12 +175,14 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
|
|
|
175
175
|
* @returns {Array} New on-condition
|
|
176
176
|
*/
|
|
177
177
|
function transformDollarSelfComparison( assocOp, assoc, assocName, elem, elemName, art, artifactName, path ) {
|
|
178
|
-
// Check: The forward link <assocOp> must point back to this artifact
|
|
178
|
+
// Check: The forward link <assocOp> must point back to this artifact.
|
|
179
|
+
// Skip when `$backlink` is present: the core compiler already validated the (possibly
|
|
180
|
+
// redirected/included) target and provided the redirected keys/on
|
|
179
181
|
// FIXME: Unfortunately, we can currently only check this for non-views (because when a view selects
|
|
180
182
|
// a backlink association element from an entity, the forward link will point to the entity,
|
|
181
183
|
// not to the view).
|
|
182
184
|
// FIXME: This also means that corresponding key fields should be in the select list etc ...
|
|
183
|
-
if (!art.query && !art.projection && assoc.target && assoc.target !== artifactName) {
|
|
185
|
+
if (!elem.$backlink && !art.query && !art.projection && assoc.target && assoc.target !== artifactName) {
|
|
184
186
|
messageFunctions.error( null, path, { id: '$self', name: artifactName, target: assoc.target },
|
|
185
187
|
'Expected association using $(ID) to point back to $(NAME) but found $(TARGET)' );
|
|
186
188
|
}
|
|
@@ -199,6 +201,16 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
|
|
|
199
201
|
return [];
|
|
200
202
|
}
|
|
201
203
|
|
|
204
|
+
// Prefer the `$backlink` helper (renaming-aware, target redirected to this artifact)
|
|
205
|
+
// over the backlink's own keys/on, so renamings are considered. Absent for
|
|
206
|
+
// same-entity backlinks, where the plain keys/on below are already correct.
|
|
207
|
+
const backlink = elem.$backlink;
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(backlink))
|
|
210
|
+
return transformDollarSelfComparisonWithUnmanagedAssoc(assocOp, assoc, assocName, elemName, art, path, backlink);
|
|
211
|
+
if (backlink?.keys?.length)
|
|
212
|
+
return transformDollarSelfComparisonWithManagedAssoc(assocOp, assoc, assocName, elemName, art, path, backlink);
|
|
213
|
+
|
|
202
214
|
if (assoc.keys) {
|
|
203
215
|
// Transform comparison of $self to managed association into AND-combined foreign key comparisons
|
|
204
216
|
if (assoc.keys.length > 0)
|
|
@@ -230,16 +242,19 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
|
|
|
230
242
|
* @param {string} elemName
|
|
231
243
|
* @param {CSN.Artifact} art
|
|
232
244
|
* @param {CSN.Path} path
|
|
245
|
+
* @param {object} [backlink] renaming-aware `elem.$backlink` (`{ keys }`) to use instead of `assoc.keys`
|
|
233
246
|
* @returns {Array} New on-condition
|
|
234
247
|
*/
|
|
235
|
-
function transformDollarSelfComparisonWithManagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path) {
|
|
248
|
+
function transformDollarSelfComparisonWithManagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path, backlink ) {
|
|
236
249
|
const conditions = [];
|
|
237
250
|
// if the element was structured then it was flattened => change of the delimiter from '.' to '_'
|
|
238
251
|
// this is done in the flattening, but as we do not alter the onCond itself there should be done here as well
|
|
239
252
|
const assocName = originalAssocName.replace(/\./g, pathDelimiter);
|
|
240
253
|
elemName = elemName.replace(/\./g, pathDelimiter);
|
|
241
254
|
|
|
242
|
-
assoc.keys
|
|
255
|
+
const keys = backlink?.keys ?? assoc.keys;
|
|
256
|
+
|
|
257
|
+
keys.forEach((k) => {
|
|
243
258
|
// Depending on naming conventions, the foreign key may two path steps (hdbcds) or be a single path step with a flattened name (plain, quoted)
|
|
244
259
|
// With to.hdbcds in conjunction with hdbcds naming, we need to NOT use the alias - else we get deployment errors
|
|
245
260
|
const keyName = k.as && doA2J ? [ k.as ] : k.ref;
|
|
@@ -282,15 +297,16 @@ function getBacklinkTransformer( csnUtils, messageFunctions, options, pathDelimi
|
|
|
282
297
|
* @param {string} elemName
|
|
283
298
|
* @param {CSN.Artifact} art
|
|
284
299
|
* @param {CSN.Path} path
|
|
300
|
+
* @param {Array} [backlink] renaming-aware `elem.$backlink` ON-condition to use instead of `assoc.on`
|
|
285
301
|
* @returns {Array} New on-condition
|
|
286
302
|
*/
|
|
287
|
-
function transformDollarSelfComparisonWithUnmanagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path ) {
|
|
303
|
+
function transformDollarSelfComparisonWithUnmanagedAssoc( assocOp, assoc, originalAssocName, elemName, art, path, backlink ) {
|
|
288
304
|
// if the element was structured then it may have been flattened => change of the delimiter from '.' to '_'
|
|
289
305
|
// this is done in the flattening, but as we do not alter the onCond itself there should be done here as well
|
|
290
306
|
elemName = elemName.replace(/\./g, pathDelimiter);
|
|
291
307
|
const assocName = originalAssocName.replace(/\./g, pathDelimiter);
|
|
292
308
|
// clone the onCond for later use in the path transformation
|
|
293
|
-
const newOnCond = cloneCsnNonDict(assoc.on, options);
|
|
309
|
+
const newOnCond = cloneCsnNonDict(backlink ?? assoc.on, options);
|
|
294
310
|
applyTransformationsOnNonDictionary({ on: newOnCond }, 'on', {
|
|
295
311
|
ref: (parent, prop, ref) => {
|
|
296
312
|
let sourceSide = false;
|
|
@@ -592,6 +592,67 @@ function createReferentialConstraints( csn, options ) {
|
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
+
/**
|
|
596
|
+
* Add an `ON DELETE CASCADE` referential constraint on the `DraftAdministrativeData_DraftUUID`
|
|
597
|
+
* foreign key of each draft shadow table, so deleting a draft's `DRAFT.DraftAdministrativeData`
|
|
598
|
+
* row removes all its shadow rows.
|
|
599
|
+
*
|
|
600
|
+
* Runs after the draft shadow entities exist (they don't during `createReferentialConstraints`).
|
|
601
|
+
* Their `DraftAdministrativeData` association is unmanaged and points at the service view, so the
|
|
602
|
+
* regular pass skips it; this pass references the `DRAFT.DraftAdministrativeData` table directly.
|
|
603
|
+
*
|
|
604
|
+
* Opt-in via the `draftAdminDataConstraints` option and independent of the global
|
|
605
|
+
* `assertIntegrity` / `assertIntegrityType` switches.
|
|
606
|
+
*
|
|
607
|
+
* @param {CSN.Model} csn
|
|
608
|
+
* @param {CSN.Options} options
|
|
609
|
+
*/
|
|
610
|
+
function createDraftAdminDataConstraints( csn, options ) {
|
|
611
|
+
if (options.draftAdminDataConstraints !== true)
|
|
612
|
+
return;
|
|
613
|
+
|
|
614
|
+
const draftAdminData = 'DRAFT.DraftAdministrativeData';
|
|
615
|
+
if (!csn.definitions[draftAdminData])
|
|
616
|
+
return;
|
|
617
|
+
|
|
618
|
+
const delimiter = options.sqlMapping === 'hdbcds' ? '.' : '_';
|
|
619
|
+
const foreignKeyName = `DraftAdministrativeData${ delimiter }DraftUUID`;
|
|
620
|
+
|
|
621
|
+
const validated = !options.integrityNotValidated;
|
|
622
|
+
const enforced = !options.integrityNotEnforced;
|
|
623
|
+
|
|
624
|
+
forEach(csn.definitions, ( artifactName, artifact ) => {
|
|
625
|
+
if (artifact.kind !== 'entity' || artifact.query || artifact.projection)
|
|
626
|
+
return;
|
|
627
|
+
const foreignKey = artifact.elements?.[foreignKeyName];
|
|
628
|
+
const assoc = artifact.elements?.DraftAdministrativeData;
|
|
629
|
+
// only draft shadow tables have both the association and its flattened foreign key
|
|
630
|
+
if (!foreignKey || !assoc || assoc.type !== ASSOCIATION)
|
|
631
|
+
return;
|
|
632
|
+
|
|
633
|
+
const identifierPrefix = options.pre2134ReferentialConstraintNames ? '' : 'c__';
|
|
634
|
+
const identifier = `${ identifierPrefix }${ getResultingName(csn, options.sqlMapping, artifactName) }_DraftAdministrativeData`;
|
|
635
|
+
const mapKey = `${ getResultingName(csn, 'quoted', artifactName) }_DraftAdministrativeData`;
|
|
636
|
+
|
|
637
|
+
if (!('$tableConstraints' in artifact))
|
|
638
|
+
artifact.$tableConstraints = Object.create(null);
|
|
639
|
+
if (!artifact.$tableConstraints.referential)
|
|
640
|
+
artifact.$tableConstraints.referential = Object.create(null);
|
|
641
|
+
|
|
642
|
+
artifact.$tableConstraints.referential[mapKey] = {
|
|
643
|
+
identifier,
|
|
644
|
+
foreignKey: [ foreignKeyName ],
|
|
645
|
+
parentKey: [ 'DraftUUID' ],
|
|
646
|
+
dependentTable: artifactName,
|
|
647
|
+
parentTable: draftAdminData,
|
|
648
|
+
onDelete: 'CASCADE',
|
|
649
|
+
onDeleteRemark: options.testMode ? 'Draft shadow entries are deleted when their DraftAdministrativeData entry is deleted' : null,
|
|
650
|
+
validated,
|
|
651
|
+
enforced,
|
|
652
|
+
};
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
|
|
595
656
|
/**
|
|
596
657
|
* If the artifact has both, unique- and foreign key constraints, it is possible that the constraints have the same identifier.
|
|
597
658
|
* This would end in table which can't be activated.
|
|
@@ -616,4 +677,4 @@ function assertConstraintIdentifierUniqueness( artifact, artifactName, path, err
|
|
|
616
677
|
});
|
|
617
678
|
}
|
|
618
679
|
|
|
619
|
-
module.exports = { createReferentialConstraints, assertConstraintIdentifierUniqueness };
|
|
680
|
+
module.exports = { createReferentialConstraints, createDraftAdminDataConstraints, assertConstraintIdentifierUniqueness };
|
|
@@ -11,7 +11,7 @@ const { isBuiltinType, isMagicVariable } = require('../../base/builtins');
|
|
|
11
11
|
const transformUtils = require('../transformUtils');
|
|
12
12
|
const { csnRefs } = require('../../base/csnRefs');
|
|
13
13
|
const { setProp, forEach } = require('../../utils/objectUtils');
|
|
14
|
-
const { transformExpression } = require('./applyTransformations');
|
|
14
|
+
const { transformExpression, isSimpleAnnoExprRef } = require('./applyTransformations');
|
|
15
15
|
const { cloneCsnNonDict } = require('../../base/cloneCsn');
|
|
16
16
|
const { EdmTypeFacetNames } = require('../../edm/EdmPrimitiveTypeDefinitions');
|
|
17
17
|
const { adaptAnnotationsRefs } = require('../odata/adaptAnnotationRefs');
|
|
@@ -246,7 +246,8 @@ function getStructStepsFlattener( csn, options, messageFunctions, resolved, path
|
|
|
246
246
|
adaptRefs.push((...args) => {
|
|
247
247
|
const refChanged = fn(...args);
|
|
248
248
|
if (refChanged && annotation['='])
|
|
249
|
-
|
|
249
|
+
// For simple refs (all-string steps, no param/cast), = contains the string representation of the ref.
|
|
250
|
+
annotation['='] = isSimpleAnnoExprRef(annotation) ? annotation.ref.join('.') : true;
|
|
250
251
|
});
|
|
251
252
|
}
|
|
252
253
|
else {
|
|
@@ -664,7 +665,7 @@ function handleManagedAssociationsAndCreateForeignKeys( csn, options, messageFun
|
|
|
664
665
|
}
|
|
665
666
|
|
|
666
667
|
if (options.transformation === 'effective') {
|
|
667
|
-
adaptAnnotationsRefs(fks, csnUtils, messageFunctions, eltPath);
|
|
668
|
+
adaptAnnotationsRefs(fks, csnUtils, messageFunctions, eltPath, options);
|
|
668
669
|
const validAnnoNames = Object.keys(element).filter(pn => pn[0] === '@' && findAnnotationExpression(element, pn));
|
|
669
670
|
fks.forEach(fk => copyAnnotations(element, fk[1], false, {}, validAnnoNames));
|
|
670
671
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { CompilerAssertion } = require('../../base/error');
|
|
4
|
+
const { transformAnnotationExpression } = require('../../model/csnUtils');
|
|
5
|
+
const { expressionToCdlString } = require('../../render/toCdl');
|
|
4
6
|
const { forEach } = require('../../utils/objectUtils');
|
|
5
7
|
|
|
6
8
|
const directMappings = {
|
|
@@ -283,6 +285,43 @@ function sealAnnoMagic(csn) {
|
|
|
283
285
|
};
|
|
284
286
|
}
|
|
285
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Replace all annotation expression nodes with their CDL-like string representation.
|
|
290
|
+
*
|
|
291
|
+
* @param {CSN.Model} _csn
|
|
292
|
+
* @param {CSN.Options} options
|
|
293
|
+
* @param {object} messageFunctions
|
|
294
|
+
* @returns {object} Transformer object for applyTransformations
|
|
295
|
+
*/
|
|
296
|
+
function stringifyAnnotationExpressions( _csn, options, messageFunctions ) {
|
|
297
|
+
// exclude '#' so enum-symbol annotation values are kept as is
|
|
298
|
+
const expressionTransformers = {
|
|
299
|
+
ref: stringifyExpression,
|
|
300
|
+
xpr: stringifyExpression,
|
|
301
|
+
list: stringifyExpression,
|
|
302
|
+
val: stringifyExpression,
|
|
303
|
+
func: stringifyExpression,
|
|
304
|
+
SELECT: stringifyExpression,
|
|
305
|
+
SET: stringifyExpression,
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
'@': (parent, prop, _anno, path) => transformAnnotationExpression(parent, prop, expressionTransformers, path),
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
function stringifyExpression( expressionNode, _prop, _value, _path, parent, parentProp ) {
|
|
313
|
+
// Keep unchecked refs that already have textual representation.
|
|
314
|
+
if (expressionNode.ref && typeof expressionNode['='] === 'string') {
|
|
315
|
+
delete expressionNode.ref;
|
|
316
|
+
delete expressionNode.param;
|
|
317
|
+
delete expressionNode.cast;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
parent[parentProp] = expressionToCdlString(expressionNode, options, messageFunctions);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
286
325
|
function isPartOfINAService(csn, artifactName) {
|
|
287
326
|
const parts = artifactName.split('.');
|
|
288
327
|
if (parts.length === 1)
|
|
@@ -339,4 +378,5 @@ function getOnConditionAsComparisonTuples(on, assocName) {
|
|
|
339
378
|
module.exports = {
|
|
340
379
|
remapODataAnnotations,
|
|
341
380
|
sealAnnoMagic,
|
|
381
|
+
stringifyAnnotationExpressions,
|
|
342
382
|
};
|
|
@@ -53,6 +53,18 @@ function flattenRefs(csn, options, csnUtils, messageFunctions) {
|
|
|
53
53
|
const refFlattener = getStructStepsFlattener(csn, options, messageFunctions, resolved, '_', adaptRefs);
|
|
54
54
|
|
|
55
55
|
forEachDefinition(csn, (def, defName) => {
|
|
56
|
+
// Unbound actions/functions/events: only flatten annotation expressions, not params.
|
|
57
|
+
// Their params may carry $self on-conditions that cannot be resolved without a query context.
|
|
58
|
+
if (def.kind === 'action' || def.kind === 'function' || def.kind === 'event') {
|
|
59
|
+
forEachMemberRecursively(def, (member, memberName, prop, path) => {
|
|
60
|
+
Object.keys(member).filter(pn => pn.startsWith('@') && member[pn]).forEach((pn) => {
|
|
61
|
+
transformAnnotationExpression(member, pn, [ refFlattener ], path);
|
|
62
|
+
adaptRefs.forEach(fn => fn());
|
|
63
|
+
adaptRefs.length = 0;
|
|
64
|
+
});
|
|
65
|
+
}, [ 'definitions', defName ]);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
56
68
|
applyTransformationsOnNonDictionary(csn.definitions, defName, refFlattener, { processAnnotations: true, skipDict: { actions: 1 } }, [ 'definitions' ]);
|
|
57
69
|
|
|
58
70
|
adaptRefs.forEach(fn => fn());
|
|
@@ -97,8 +109,12 @@ function flattenRefs(csn, options, csnUtils, messageFunctions) {
|
|
|
97
109
|
});
|
|
98
110
|
|
|
99
111
|
cleanup.forEach((obj) => {
|
|
100
|
-
|
|
112
|
+
// strip leading $self from ref array and (if it is a string) from '='
|
|
113
|
+
if (obj.ref && obj.ref[0] === '$self') {
|
|
101
114
|
obj.ref.shift();
|
|
115
|
+
if (typeof obj['='] === 'string' && obj['='].startsWith('$self.'))
|
|
116
|
+
obj['='] = obj['='].slice('$self.'.length);
|
|
117
|
+
}
|
|
102
118
|
});
|
|
103
119
|
}
|
|
104
120
|
|
|
@@ -103,6 +103,25 @@ function effectiveCsn( model, options, messageFunctions ) {
|
|
|
103
103
|
|
|
104
104
|
resolveTypesInActionsAfterFlattening(csnUtils);
|
|
105
105
|
|
|
106
|
+
// Rewrite association keys in unbound action/function params to use flattened names.
|
|
107
|
+
// Not needed for bound actions: their params are reached via the parent entity and handled by flattenFKs in managedToUnmanaged.
|
|
108
|
+
forEachDefinition(csn, (def) => {
|
|
109
|
+
if (def.kind !== 'action' && def.kind !== 'function')
|
|
110
|
+
return;
|
|
111
|
+
if (!def.params)
|
|
112
|
+
return;
|
|
113
|
+
for (const param of Object.values(def.params)) {
|
|
114
|
+
if (!param.elements)
|
|
115
|
+
continue;
|
|
116
|
+
for (const element of Object.values(param.elements)) {
|
|
117
|
+
if (element.keys)
|
|
118
|
+
element.keys.forEach((key) => {
|
|
119
|
+
key.ref = [ key.ref.join('_') ];
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
106
125
|
processCalculatedElementsInEntities(csn, options);
|
|
107
126
|
// invalidate csnRef caches after flattening
|
|
108
127
|
transformerUtils.csnUtils = getUtils(csn, 'init-all');
|
|
@@ -113,6 +132,7 @@ function effectiveCsn( model, options, messageFunctions ) {
|
|
|
113
132
|
options.remapOdataAnnotations ? annotations.remapODataAnnotations(csn) : {},
|
|
114
133
|
misc.removeDefinitionsAndProperties(csn, options),
|
|
115
134
|
options.deriveAnalyticalAnnotations ? annotations.sealAnnoMagic(csn) : {},
|
|
135
|
+
options.stringifyAnnoXpr ? annotations.stringifyAnnotationExpressions(csn, options, messageFunctions) : {},
|
|
116
136
|
], null);
|
|
117
137
|
|
|
118
138
|
if (options.addCdsPersistenceName) {
|
|
@@ -16,7 +16,7 @@ const { isBuiltinType } = require('../base/builtins');
|
|
|
16
16
|
* - the foreign key is of scalar type
|
|
17
17
|
* Otherwise, appropriate warnings/errors are raised.
|
|
18
18
|
*/
|
|
19
|
-
function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunctions, csnUtils, transformers, options) {
|
|
19
|
+
function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunctions, csnUtils, transformers, options, csn) {
|
|
20
20
|
const { error, warning } = messageFunctions;
|
|
21
21
|
const { isAssociation } = csnUtils;
|
|
22
22
|
const { setAnnotation, addElement, createScalarElement } = transformers;
|
|
@@ -157,6 +157,17 @@ function generateFioriTreeViewAnnotationsAndFields(def, defName, messageFunction
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
function addHierarchyFields(def, defName) {
|
|
160
|
+
addHierarchyFieldsTo(def, defName);
|
|
161
|
+
|
|
162
|
+
// The localized convenience view is a stand-in for the annotated view at
|
|
163
|
+
// runtime, so it must carry the same hierarchy columns. It is generated
|
|
164
|
+
// before this transform runs, hence it is augmented here explicitly.
|
|
165
|
+
const localizedView = csn?.definitions?.[`localized.${ defName }`];
|
|
166
|
+
if (localizedView)
|
|
167
|
+
addHierarchyFieldsTo(localizedView, `localized.${ defName }`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function addHierarchyFieldsTo(def, defName) {
|
|
160
171
|
// add elements in elements dictionary
|
|
161
172
|
const limitedDescendantCount = createScalarElement('LimitedDescendantCount', 'cds.Integer');
|
|
162
173
|
limitedDescendantCount.LimitedDescendantCount['@Core.Computed'] = true;
|
|
@@ -17,7 +17,7 @@ const validate = require('../checks/validator');
|
|
|
17
17
|
const { addTenantFields } = require('../transform/addTenantFields');
|
|
18
18
|
const { addLocalizationViewsWithJoins } = require('../transform/localized');
|
|
19
19
|
const { timetrace } = require('../utils/timetrace');
|
|
20
|
-
const { createReferentialConstraints, assertConstraintIdentifierUniqueness } = require('./db/constraints');
|
|
20
|
+
const { createReferentialConstraints, createDraftAdminDataConstraints, assertConstraintIdentifierUniqueness } = require('./db/constraints');
|
|
21
21
|
const { setProp, forEach } = require('../utils/objectUtils');
|
|
22
22
|
const handleExists = require('./db/assocsToQueries/transformExists');
|
|
23
23
|
const { rewriteCalculatedElementsInViews, processCalculatedElementsInEntities } = require('./db/rewriteCalculatedElements');
|
|
@@ -340,6 +340,11 @@ function transformForRelationalDBWithCsn(csn, options, messageFunctions) {
|
|
|
340
340
|
// no constraints for drafts
|
|
341
341
|
generateDrafts(csn, options, pathDelimiter, messageFunctions);
|
|
342
342
|
|
|
343
|
+
// the DraftAdministrativeData_DraftUUID foreign key still gets a cascade constraint;
|
|
344
|
+
// must run after generateDrafts, as the shadow tables don't exist before
|
|
345
|
+
if (options.sqlDialect !== 'plain' && options.sqlDialect !== 'h2')
|
|
346
|
+
createDraftAdminDataConstraints(csn, options);
|
|
347
|
+
|
|
343
348
|
// Set the final constraint paths and produce hana tc indexes if required
|
|
344
349
|
// See function comment for extensive information.
|
|
345
350
|
assertUnique.rewrite(csn, options, pathDelimiter);
|
|
@@ -362,7 +367,7 @@ function transformForRelationalDBWithCsn(csn, options, messageFunctions) {
|
|
|
362
367
|
findAndMarkSqlServiceArtifacts(artifact, artifactName);
|
|
363
368
|
if (artifact.$dummyService)
|
|
364
369
|
createServiceDummy(artifact, artifactName, csn, messageFunctions);
|
|
365
|
-
generateFioriTreeViews(artifact, artifactName, messageFunctions, csnUtils, { setAnnotation, addElement, createScalarElement }, options);
|
|
370
|
+
generateFioriTreeViews(artifact, artifactName, messageFunctions, csnUtils, { setAnnotation, addElement, createScalarElement }, options, csn);
|
|
366
371
|
}, transformViews ]);
|
|
367
372
|
|
|
368
373
|
// TODO: Could we maybe merge this with the final applyTransformations?
|