@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
|
@@ -7,7 +7,7 @@ modules:
|
|
|
7
7
|
builder: proxy-unified-runtime-dmz.int.repositories.cloud.sap/builder/noble
|
|
8
8
|
{{/hasKymaUnifiedRuntime}}
|
|
9
9
|
{{^hasKymaUnifiedRuntime}}
|
|
10
|
-
type: sapse/application-content-deployer-buildpack:1.
|
|
10
|
+
type: sapse/application-content-deployer-buildpack:1.5.0
|
|
11
11
|
builder: builder-jammy-base
|
|
12
12
|
{{/hasKymaUnifiedRuntime}}
|
|
13
|
-
path:
|
|
13
|
+
path: {{& html5DeployerPath}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { readProject } = require('../../projectReader')
|
|
2
2
|
const { merge } = require('../../merge')
|
|
3
3
|
const { srv4, appDeployer, appFront, xsuaa } = require('../../registries/mta')
|
|
4
|
-
const {
|
|
4
|
+
const { srvApi } = require('../../registries/xs-app')
|
|
5
5
|
const { renderAndCopy } = require('../../template')
|
|
6
6
|
const { sh:$, path:{join}, fs:{promises:{rename}}, write, read, exists } = require('../../../cds').utils
|
|
7
7
|
|
|
@@ -50,8 +50,8 @@ module.exports = class extends require('../../plugin') {
|
|
|
50
50
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
async combine() {
|
|
54
|
-
const project = readProject()
|
|
53
|
+
async combine(facet) {
|
|
54
|
+
const project = readProject(facet)
|
|
55
55
|
const {
|
|
56
56
|
srv, appPath, apps,
|
|
57
57
|
hasMta, addMta, hasXsuaa, addSample, addApprouter, addWorkzoneStandard, addXsuaa, addIas,
|
|
@@ -61,7 +61,7 @@ module.exports = class extends require('../../plugin') {
|
|
|
61
61
|
await Promise.all(apps.map(async ({ app }) => {
|
|
62
62
|
project.app = app
|
|
63
63
|
project.hasIndexHtml = exists(join(appPath, app, 'webapp/index.html'))
|
|
64
|
-
const additions = [
|
|
64
|
+
const additions = [srvApi]
|
|
65
65
|
await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions })
|
|
66
66
|
}))
|
|
67
67
|
|
|
@@ -26,8 +26,8 @@ module.exports = class ApplicationLoggingTemplate extends require('../../plugin'
|
|
|
26
26
|
if (isJava) await mvn.add('APPLICATION_LOGGING')
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
async combine() {
|
|
30
|
-
const project = readProject()
|
|
29
|
+
async combine(facet) {
|
|
30
|
+
const project = readProject(facet)
|
|
31
31
|
const { addMta, hasMta, hasApprouter, isJava, addMultitenancy, hasMultitenancy, srv } = project
|
|
32
32
|
|
|
33
33
|
if (addMta || (addMultitenancy && hasMta)) {
|
|
@@ -31,8 +31,8 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
|
|
|
31
31
|
await merge(__dirname, 'files/default-env.json').into(approuterPath + '/default-env.json')
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
async combine() {
|
|
35
|
-
const project = readProject()
|
|
34
|
+
async combine(facet) {
|
|
35
|
+
const project = readProject(facet)
|
|
36
36
|
const {
|
|
37
37
|
isNodejs, isJava,
|
|
38
38
|
addIas, addXsuaa, hasXsuaa, hasIas, addMultitenancy, hasMTXRoute, hasMTXRouteJava,
|
|
@@ -51,6 +51,7 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
|
|
|
51
51
|
if (hasMultitenancy) modules.push(mtxSidecar)
|
|
52
52
|
const additions = [...modules, ...apis]
|
|
53
53
|
const relationships = []
|
|
54
|
+
const deletions = []
|
|
54
55
|
if (hasXsuaa) {
|
|
55
56
|
relationships.push({
|
|
56
57
|
insert: [xsuaa, 'name'],
|
|
@@ -62,9 +63,13 @@ module.exports = class ApprouterTemplate extends require('../../plugin') {
|
|
|
62
63
|
insert: [ias, 'name'],
|
|
63
64
|
into: [approuter, 'requires', 'name']
|
|
64
65
|
})
|
|
66
|
+
deletions.push({
|
|
67
|
+
item: { in: [approuter, 'requires'], where: { 'name': 'srv-api' } },
|
|
68
|
+
key: 'properties.name'
|
|
69
|
+
})
|
|
65
70
|
}
|
|
66
71
|
await merge(__dirname, 'files/mta.yaml.hbs').into('mta.yaml', {
|
|
67
|
-
with: project, additions, relationships,
|
|
72
|
+
with: project, additions, relationships, deletions,
|
|
68
73
|
})
|
|
69
74
|
}
|
|
70
75
|
|
|
@@ -25,8 +25,8 @@ module.exports = class AttachmentsTemplate extends require('../../plugin') {
|
|
|
25
25
|
if (isJava) await mvn.add('attachments')
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
async combine() {
|
|
29
|
-
const project = readProject()
|
|
28
|
+
async combine(facet) {
|
|
29
|
+
const project = readProject(facet)
|
|
30
30
|
const { addMta, addKyma, srv } = project
|
|
31
31
|
|
|
32
32
|
if (addMta) {
|
|
@@ -32,8 +32,8 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
|
|
|
32
32
|
if (isJava) await mvn.add('audit_logging')
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
async combine() {
|
|
36
|
-
const project = readProject()
|
|
35
|
+
async combine(facet) {
|
|
36
|
+
const project = readProject(facet)
|
|
37
37
|
const { addMta, addKyma, addMultitenancy, srv } = project
|
|
38
38
|
const { plan = 'premium' } = cds.cli.options
|
|
39
39
|
project.servicePlan = plan
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
{{#withTelemetry}}
|
|
3
3
|
"dependencies": {
|
|
4
|
-
"@cap-js/telemetry": "
|
|
4
|
+
"@cap-js/telemetry": "^2",
|
|
5
5
|
"@grpc/grpc-js": "^1",
|
|
6
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "
|
|
7
|
-
"@opentelemetry/exporter-metrics-otlp-grpc": "
|
|
8
|
-
"@opentelemetry/host-metrics": "
|
|
6
|
+
"@opentelemetry/exporter-trace-otlp-grpc": ">=0.200",
|
|
7
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": ">=0.200",
|
|
8
|
+
"@opentelemetry/instrumentation-host-metrics": ">=0.2"
|
|
9
9
|
},
|
|
10
10
|
{{/withTelemetry}}
|
|
11
11
|
"cds": {
|
|
@@ -38,8 +38,8 @@ module.exports = class extends require('../../plugin') {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
async combine() {
|
|
42
|
-
const project = readProject()
|
|
41
|
+
async combine(facet) {
|
|
42
|
+
const project = readProject(facet)
|
|
43
43
|
const { hasMta, addMta, addKyma, addApprouter, isJava, addMultitenancy, srv } = project
|
|
44
44
|
|
|
45
45
|
if (addMta || (addMultitenancy || addApprouter) && hasMta) {
|
|
@@ -16,26 +16,33 @@ const SUPPORTED_SHELLS = [...SUPPORTED_LINUX_SHELLS, ...SUPPORTED_WINDOWS_SHELLS
|
|
|
16
16
|
module.exports = new class CompletionSetup {
|
|
17
17
|
supportedShells = SUPPORTED_SHELLS
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
resolveShell(options) {
|
|
20
|
+
return options?.shell
|
|
21
21
|
|| (process.env.MSYSTEM?.includes('MINGW64') ? 'gitbash' : process.env.SHELL?.match(/(bash|fish|zsh)/)?.[0])
|
|
22
22
|
|| (process.env.PSModulePath ? 'ps' : null);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async setup(addEntry, options) {
|
|
26
|
+
const shell = this.resolveShell(options);
|
|
23
27
|
|
|
24
28
|
switch (shell) {
|
|
25
29
|
case 'bash':
|
|
26
30
|
case 'fish':
|
|
27
31
|
case 'gitbash':
|
|
28
32
|
case 'zsh':
|
|
29
|
-
|
|
33
|
+
await this.setupLinuxLike(addEntry, shell);
|
|
34
|
+
return shell;
|
|
30
35
|
case 'ps':
|
|
31
|
-
|
|
36
|
+
await this.setupPs(addEntry);
|
|
37
|
+
return shell;
|
|
32
38
|
case null:
|
|
33
39
|
try {
|
|
34
40
|
const shellType = this.determineShellLinux();
|
|
35
41
|
if (!shellType) {
|
|
36
42
|
throw `Unsupported shell.\nSupported shells are: ${SUPPORTED_SHELLS.join(', ')}.`;
|
|
37
43
|
}
|
|
38
|
-
|
|
44
|
+
await this.setupLinuxLike(addEntry, shellType);
|
|
45
|
+
return shellType;
|
|
39
46
|
} catch (err) {
|
|
40
47
|
throw `Error during completion setup: ${err}`;
|
|
41
48
|
}
|
|
@@ -95,7 +102,7 @@ module.exports = new class CompletionSetup {
|
|
|
95
102
|
|
|
96
103
|
profileFile = path.join(os.homedir(), profileFile);
|
|
97
104
|
|
|
98
|
-
await this.changeProfile(profileFile, shell, addEntry);
|
|
105
|
+
await this.changeProfile(profileFile, shell, addEntry, this.resolveScriptPath(shell));
|
|
99
106
|
|
|
100
107
|
const relProfilePath = path.relative(os.homedir(), profileFile);
|
|
101
108
|
console.log(`\nSource your shell using\n${bold(`source ~/${relProfilePath}`)}\nto activate the changes.\n`);
|
|
@@ -113,55 +120,45 @@ module.exports = new class CompletionSetup {
|
|
|
113
120
|
throw err;
|
|
114
121
|
}
|
|
115
122
|
|
|
116
|
-
await this.changeProfile(profilePath, 'ps', addEntry);
|
|
123
|
+
await this.changeProfile(profilePath, 'ps', addEntry, this.resolveScriptPath('ps'));
|
|
117
124
|
console.log(`\nSource your shell using\n${bold('. $PROFILE')}\nto activate the changes.`);
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
// Returns the absolute path to the pre-generated cache file bundled with this package.
|
|
128
|
+
resolveScriptPath(shell) {
|
|
129
|
+
const cacheFiles = { bash: 'cds.sh', gitbash: 'cds.sh', fish: 'cds.fish', ps: 'cds.ps1', zsh: 'cds.zsh' };
|
|
130
|
+
return path.join(__dirname, '../../../../bin/completion/scripts', cacheFiles[shell]);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Generates the snippet written to the user's shell profile. The script path is hardcoded at
|
|
134
|
+
// install time to avoid spawning a subprocess on every shell startup.
|
|
135
|
+
getScript(shell, scriptPath) {
|
|
121
136
|
switch (shell) {
|
|
122
137
|
case 'bash':
|
|
123
138
|
case 'gitbash':
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
if [ -r "$CDS_PROFILE" ]; then
|
|
127
|
-
. "$CDS_PROFILE"
|
|
128
|
-
fi
|
|
129
|
-
`
|
|
139
|
+
return `# cds shell completion script (path resolved at install time)
|
|
140
|
+
_p="${scriptPath}" && [ -r "$_p" ] && . "$_p"`
|
|
130
141
|
case 'fish':
|
|
131
|
-
return
|
|
142
|
+
return `# cds shell completion script (path resolved at install time)
|
|
132
143
|
if type "cds" >/dev/null 2>&1
|
|
133
|
-
set -l
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
`
|
|
144
|
+
set -l _p "${scriptPath}"
|
|
145
|
+
test -r "$_p" && source "$_p"
|
|
146
|
+
end`
|
|
139
147
|
case 'ps':
|
|
140
|
-
return
|
|
141
|
-
|
|
142
|
-
$CDS_PROFILE = cds completion --shell ps --profile 2> $null
|
|
143
|
-
if (Test-Path -Path "$CDS_PROFILE" -PathType Leaf) {
|
|
144
|
-
. "$CDS_PROFILE"
|
|
145
|
-
}
|
|
146
|
-
} catch {}
|
|
147
|
-
`
|
|
148
|
-
|
|
148
|
+
return `# cds shell completion script (path resolved at install time)
|
|
149
|
+
$_p = "${scriptPath}"; if (Test-Path -Path "$_p" -PathType Leaf) { . "$_p" }`
|
|
149
150
|
case 'zsh':
|
|
150
|
-
return
|
|
151
|
-
# compinit can be removed here if loaded elsewhere in the script
|
|
151
|
+
return `# compinit can be removed here if loaded elsewhere in the script
|
|
152
152
|
autoload -Uz compinit && compinit
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
. "$CDS_PROFILE"
|
|
157
|
-
fi
|
|
158
|
-
`
|
|
154
|
+
# cds shell completion script (path resolved at install time)
|
|
155
|
+
_p="${scriptPath}" && [ -r "$_p" ] && \\. "$_p"`
|
|
159
156
|
default:
|
|
160
157
|
throw `Unsupported shell: ${shell}`;
|
|
161
158
|
}
|
|
162
159
|
}
|
|
163
160
|
|
|
164
|
-
async changeProfile(profileFile, shell, addEntry) {
|
|
161
|
+
async changeProfile(profileFile, shell, addEntry, scriptPath) {
|
|
165
162
|
let profile = '';
|
|
166
163
|
let profileFileExists = true;
|
|
167
164
|
try {
|
|
@@ -181,7 +178,7 @@ fi
|
|
|
181
178
|
profile = profile + `
|
|
182
179
|
|
|
183
180
|
# cds completion start
|
|
184
|
-
${this.getScript(shell)}
|
|
181
|
+
${this.getScript(shell, scriptPath)}
|
|
185
182
|
# cds completion end`;
|
|
186
183
|
changed = true;
|
|
187
184
|
}
|
|
@@ -18,8 +18,8 @@ module.exports = class ConnectivityTemplate extends require('../../plugin') {
|
|
|
18
18
|
await merge(__dirname, 'files', 'package.json.hbs').into(configFile, { with: project })
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
async combine() {
|
|
22
|
-
const project = readProject()
|
|
21
|
+
async combine(facet) {
|
|
22
|
+
const project = readProject(facet)
|
|
23
23
|
const { srv, addKyma, addMta } = project
|
|
24
24
|
|
|
25
25
|
if (addMta) {
|
|
@@ -4,10 +4,10 @@ const { elementsSorter } = require('./as-json')
|
|
|
4
4
|
* Serializes the given JSON data to CSV format
|
|
5
5
|
* @param {object} data JSON data to serialize
|
|
6
6
|
* @param {object} csn the model
|
|
7
|
-
* @param {{ headerOnly: boolean, separator: boolean }} options
|
|
7
|
+
* @param {{ headerOnly: boolean, keysOnly: boolean, separator: boolean }} options
|
|
8
8
|
* @returns {Promise<string>} CSV string
|
|
9
9
|
*/
|
|
10
|
-
module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) => {
|
|
10
|
+
module.exports = async (data={}, csn, { headerOnly=false, keysOnly=false, separator=',' }={}) => {
|
|
11
11
|
|
|
12
12
|
// We might need multiple passes if data for associations/compositions is created on the fly.
|
|
13
13
|
// So loop as long as there is some non-string data left.
|
|
@@ -32,6 +32,15 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
|
|
|
32
32
|
if (data[t] === undefined) {
|
|
33
33
|
data[t] = value // Add object for a new entity. Next pass will process it.
|
|
34
34
|
}
|
|
35
|
+
// managed to-one composition: emit the foreign-key column(s) on the parent, like an association
|
|
36
|
+
if (!element.on && element.keys) {
|
|
37
|
+
const targetRecord = Array.isArray(value) ? value[0] : value
|
|
38
|
+
const fk = {}
|
|
39
|
+
if (targetRecord) for (const k of element.keys) fk[k.ref[k.ref.length - 1]] = targetRecord[k.ref[k.ref.length - 1]]
|
|
40
|
+
const {headers: fkHeaders, records: fkRecords} = resolveStruct(fk, name)
|
|
41
|
+
if (i === 0) header.push(...fkHeaders)
|
|
42
|
+
record.push(...(keysOnly && !element.key ? fkRecords.map(() => '') : fkRecords))
|
|
43
|
+
}
|
|
35
44
|
}
|
|
36
45
|
else if (element._type === 'cds.Association') {
|
|
37
46
|
if (element.on) {
|
|
@@ -42,18 +51,19 @@ module.exports = async (data={}, csn, { headerOnly=false, separator=',' }={}) =>
|
|
|
42
51
|
if (i === 0) {
|
|
43
52
|
header.push(...fkHeaders)
|
|
44
53
|
}
|
|
45
|
-
|
|
54
|
+
// foreign keys of key associations are part of the primary key and must be kept
|
|
55
|
+
record.push(...(keysOnly && !element.key ? fkRecords.map(() => '') : fkRecords))
|
|
46
56
|
}
|
|
47
57
|
else if (element.is_struct && element.type !== 'cds.Map') {
|
|
48
58
|
const {headers: structHeaders, records: structRecords} = resolveStruct(value, name);
|
|
49
59
|
if (i === 0) {
|
|
50
60
|
header.push(...structHeaders)
|
|
51
61
|
}
|
|
52
|
-
record.push(...structRecords)
|
|
62
|
+
record.push(...(keysOnly && !element.key ? structRecords.map(() => '') : structRecords))
|
|
53
63
|
}
|
|
54
64
|
else {
|
|
55
65
|
if (i === 0) header.push(name)
|
|
56
|
-
record.push(processValue(value))
|
|
66
|
+
record.push(keysOnly && !element.key ? '' : processValue(value))
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
records.push(record.join(separator))
|
|
@@ -4,6 +4,8 @@ const cds = require('../../../cds')
|
|
|
4
4
|
|
|
5
5
|
let counter = Math.round(Math.random() * 10000) // Default random seed // Non-deterministic behaviour
|
|
6
6
|
const MAX_ASSOC_DEPTH = 5
|
|
7
|
+
let compositionRecords = 2 // number of records generated per to-many composition
|
|
8
|
+
let requestedRecords = 1 // number of records requested per entity, used to spread association keys
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Creates JSON test data for the given entities
|
|
@@ -16,6 +18,8 @@ const MAX_ASSOC_DEPTH = 5
|
|
|
16
18
|
*/
|
|
17
19
|
const asJson = module.exports = async (data, csn, numRecords=1, options={}) => {
|
|
18
20
|
let { referenceData, contentType, artifact='entity' } = options
|
|
21
|
+
compositionRecords = Number(options.compositionRecords) > 0 ? Number(options.compositionRecords) : 2
|
|
22
|
+
requestedRecords = Number(numRecords) > 0 ? Number(numRecords) : 1
|
|
19
23
|
|
|
20
24
|
// if no data is given, use all data
|
|
21
25
|
if (!data) {
|
|
@@ -120,8 +124,11 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
120
124
|
|
|
121
125
|
if (element.items?.elements) // `array of` / `many` with complex type
|
|
122
126
|
return [ fillRecord({}, record['$id'], element.items, csn, data, null, depth+1, referenceData) ]
|
|
123
|
-
else if (element.items?.type) // `array of` / `many` with simple type
|
|
124
|
-
|
|
127
|
+
else if (element.items?.type) { // `array of` / `many` with simple type
|
|
128
|
+
// `@assert.range` sits on the outer element, not on items, so carry it over
|
|
129
|
+
const items = element['@assert.range'] ? { ...element.items, '@assert.range': element['@assert.range'] } : element.items
|
|
130
|
+
return [ dataForField(items, artifact, csn, record, data, null, depth+1, referenceData) ]
|
|
131
|
+
}
|
|
125
132
|
|
|
126
133
|
if (element.is_struct) {
|
|
127
134
|
let struct = {}
|
|
@@ -134,11 +141,18 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
134
141
|
|
|
135
142
|
const type = element._type || element.type
|
|
136
143
|
switch (type) {
|
|
137
|
-
case 'cds.Time':
|
|
138
|
-
|
|
144
|
+
case 'cds.Time': {
|
|
145
|
+
// vary time across records instead of a fixed constant
|
|
146
|
+
const pad = n => String(n).padStart(2, '0')
|
|
147
|
+
const hh = pad(randomIntInRange({ from: 0, to: 23 }))
|
|
148
|
+
const mm = pad(randomIntInRange({ from: 0, to: 59 }))
|
|
149
|
+
const ss = pad(randomIntInRange({ from: 0, to: 59 }))
|
|
150
|
+
return `${hh}:${mm}:${ss}`
|
|
151
|
+
}
|
|
139
152
|
|
|
140
153
|
case 'cds.Timestamp': {
|
|
141
154
|
const range = {from: new Date('2000-01-01'), to: new Date('2024-01-01')}
|
|
155
|
+
annotatedDateRange(element, range) // honor @assert.range bounds
|
|
142
156
|
return randomDateInRange(range).toISOString()
|
|
143
157
|
}
|
|
144
158
|
case 'cds.Date': {
|
|
@@ -228,18 +242,23 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
228
242
|
case 'cds.hana.REAL':
|
|
229
243
|
case 'cds.Decimal': { // Decimal(9,5), Decimal(9), Decimal(precision:5), Decimal(2,2)
|
|
230
244
|
const scale = element.scale ?? (element.precision ? 0 : 2) // scale is 0 if only precision is given
|
|
231
|
-
//
|
|
232
|
-
const prec = element.precision ? Math.min(Math.pow(10, element.precision - scale) -
|
|
245
|
+
// largest value representable with the given precision/scale, e.g. Decimal(2,2) -> 0.99, Decimal(4,2) -> 99.99
|
|
246
|
+
const prec = element.precision ? Math.min(Math.pow(10, element.precision - scale) - Math.pow(10, -scale), Number.MAX_SAFE_INTEGER) : 100
|
|
233
247
|
const range = { from: 0, to: prec }
|
|
234
248
|
annotatedIntRange(element, range)
|
|
235
249
|
if (scale === 0) return randomIntInRange(range)
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
const factor = Math.pow(10, scale)
|
|
251
|
+
range.from = Math.ceil(range.from * factor) / factor
|
|
252
|
+
range.to = Math.floor(range.to * factor) / factor
|
|
253
|
+
// draw uniformly across the range and round to scale, so annotated bounds are never exceeded
|
|
254
|
+
const val = +randomDecimalInRange(range).toFixed(scale)
|
|
255
|
+
return +Math.min(Math.max(val, range.from), range.to).toFixed(scale)
|
|
239
256
|
}
|
|
240
257
|
case 'cds.Double': {
|
|
241
258
|
const range = {from: 0, to: 100}
|
|
242
|
-
|
|
259
|
+
annotatedIntRange(element, range) // honor @assert.range bounds
|
|
260
|
+
const val = randomDecimalInRange(range)
|
|
261
|
+
return Math.min(Math.max(val, range.from), range.to)
|
|
243
262
|
}
|
|
244
263
|
case 'cds.Composition': {
|
|
245
264
|
const target = csn.definitions[element.target]
|
|
@@ -248,7 +267,7 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
248
267
|
let targetRecords = [] // in findKeysInOnCondition target records are linked to the entity, we don't want to overwrite any existing data
|
|
249
268
|
if (data[target.name]) data[target.name].deleteReference = true // for json composites references are nested and will be deleted when writing to file
|
|
250
269
|
|
|
251
|
-
const targetRecordCount = element.is2many ?
|
|
270
|
+
const targetRecordCount = element.is2many ? compositionRecords : 1
|
|
252
271
|
const targetRecordID = randomNumber()
|
|
253
272
|
for (let i = 0; i < targetRecordCount; i++) {
|
|
254
273
|
const newRecord = fillRecord({}, targetRecordID+i, target, csn, data, artifact, depth+1, referenceData)
|
|
@@ -291,31 +310,52 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
|
|
|
291
310
|
return
|
|
292
311
|
|
|
293
312
|
if (targetRecords.length > 0) { // use record generated by following association
|
|
294
|
-
|
|
313
|
+
// spread across fully-built targets so composite association keys vary; fall back to the last (still-building) record for circular refs
|
|
314
|
+
const targetKeys = Object.keys(target.elements).filter(k => target.elements[k].key)
|
|
315
|
+
const ready = targetRecords.filter(r => targetKeys.every(k => r[k] !== undefined))
|
|
316
|
+
targetRecord = ready.length ? ready[pickIndex(record['$id'], element.name, ready.length)] : targetRecords.at(-1)
|
|
295
317
|
} else {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
318
|
+
// a key association needs distinct targets across rows, else the composite key collapses to one row;
|
|
319
|
+
// seed a pool up to the requested record count so later rows can spread across it
|
|
320
|
+
let poolSize = element.key && target.name !== artifact.name ? requestedRecords : 1
|
|
321
|
+
// a self-referential link (2+ key associations to the same target) needs at least 2 targets to pair distinct rows
|
|
322
|
+
const keyAssocsToTarget = Object.values(artifact.elements).filter(e => e.key && e.target === element.target).length
|
|
323
|
+
if (keyAssocsToTarget > 1) poolSize = Math.max(poolSize, keyAssocsToTarget)
|
|
324
|
+
for (let p = 0; p < poolSize; p++) {
|
|
325
|
+
const rec = fillRecord({}, randomNumber(), target, csn, data, artifact, depth+1, referenceData)
|
|
326
|
+
if (rec) targetRecords.push(rec)
|
|
300
327
|
}
|
|
328
|
+
uniqRecords(targetRecords, target)
|
|
329
|
+
targetRecord = targetRecords.length ? targetRecords[pickIndex(record['$id'], element.name, targetRecords.length)] : undefined
|
|
301
330
|
if (parent && (parent.name != artifact.name)) data[target.name].keepReference = true
|
|
302
331
|
}
|
|
303
332
|
}
|
|
304
333
|
|
|
305
|
-
//
|
|
334
|
+
// build the foreign key from all of the target's keys, recursing into keys that are themselves associations
|
|
306
335
|
const assoc = {}
|
|
307
336
|
Object.keys(target.elements)
|
|
308
337
|
.filter(keyName => target.elements[keyName].key)
|
|
309
|
-
.forEach(keyName =>
|
|
338
|
+
.forEach(keyName => {
|
|
339
|
+
const keyEl = target.elements[keyName]
|
|
340
|
+
assoc[keyName] = keyEl.target
|
|
341
|
+
? dataForField(keyEl, target, csn, targetRecord, data, artifact, depth+1, referenceData)
|
|
342
|
+
: targetRecord[keyName]
|
|
343
|
+
})
|
|
310
344
|
return assoc
|
|
311
345
|
}
|
|
312
346
|
|
|
313
347
|
case 'cds.hana.BINARY':
|
|
314
348
|
case 'cds.Binary':
|
|
315
|
-
case 'cds.LargeBinary':
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
349
|
+
case 'cds.LargeBinary': {
|
|
350
|
+
const bytes = element.length ? Math.min(element.length, 16) : 8
|
|
351
|
+
const buf = Buffer.alloc(bytes)
|
|
352
|
+
for (let i = 0; i < bytes; i++) buf[i] = randomNumber() % 256
|
|
353
|
+
return buf.toString('base64')
|
|
354
|
+
}
|
|
355
|
+
case 'cds.Vector': {
|
|
356
|
+
const dim = element.dimension ?? element.length ?? 3
|
|
357
|
+
return JSON.stringify(Array.from({ length: dim }, () => +randomUnit().toFixed(6)))
|
|
358
|
+
}
|
|
319
359
|
default: {
|
|
320
360
|
console.error(`Unknown type ${element._type} (${element.type}) in '${artifact.name}:${element.name}'`)
|
|
321
361
|
return
|
|
@@ -391,7 +431,8 @@ function findKeysInOnCondition(assocElement, target) {
|
|
|
391
431
|
targetKey = ref[1]
|
|
392
432
|
}
|
|
393
433
|
else if (ref[0] === '$self') {
|
|
394
|
-
|
|
434
|
+
// structured foreign key: carry over the parent's full (possibly composite) key set
|
|
435
|
+
ownKey = Object.keys(assocElement.parent.keys || {})[0]
|
|
395
436
|
ownKeyStructured = true
|
|
396
437
|
}
|
|
397
438
|
else if (assocElement.parent.elements[ref[0]]) {
|
|
@@ -407,7 +448,8 @@ function uniqRecords(records, artifact) {
|
|
|
407
448
|
if (keys.length === 0) keys.push('$id') // no keys (e.g. in actions) -> use record's $id
|
|
408
449
|
const keySet = new Set()
|
|
409
450
|
for (let i = 0; i < records.length; i++) {
|
|
410
|
-
|
|
451
|
+
// JSON-serialize so association-typed keys (object foreign keys) compare by value, not '[object Object]'
|
|
452
|
+
const key = keys.map(k => JSON.stringify(records[i][k])).join('|')
|
|
411
453
|
if (keySet.has(key)) {
|
|
412
454
|
// console.debug('Removing', keys, key, 'from', artifact.name)
|
|
413
455
|
records.splice(i, 1)
|
|
@@ -420,29 +462,60 @@ function uniqRecords(records, artifact) {
|
|
|
420
462
|
|
|
421
463
|
function annotatedDateRange(el, dateRange) {
|
|
422
464
|
if (el['@assert.range']?.length === 2) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
465
|
+
let from = dateBound(el['@assert.range'][0], true)
|
|
466
|
+
let to = dateBound(el['@assert.range'][1], false)
|
|
467
|
+
const YEAR = 10 * 365 * 24 * 60 * 60 * 1000 // anchor window for open-ended bounds
|
|
468
|
+
if (from === Infinity || from === -Infinity) from = to instanceof Date ? new Date(to.valueOf() - YEAR) : dateRange.from
|
|
469
|
+
if (to === Infinity || to === -Infinity) to = from instanceof Date ? new Date(from.valueOf() + YEAR) : dateRange.to
|
|
470
|
+
// use annotated bounds directly, so ranges outside the default window don't invert
|
|
471
|
+
if (from instanceof Date && !isNaN(from)) dateRange.from = from
|
|
472
|
+
if (to instanceof Date && !isNaN(to)) dateRange.to = to
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// resolve one date @assert.range bound: ISO string, open-interval xpr {xpr:[y,'-',m,'-',d]}, or infinity {'=':'_'}
|
|
477
|
+
function dateBound(bound, isLower) {
|
|
478
|
+
if (bound && typeof bound === 'object') {
|
|
479
|
+
if (bound.val === '_' || bound['='] === '_') return isLower ? -Infinity : Infinity
|
|
480
|
+
if (Array.isArray(bound.xpr)) {
|
|
481
|
+
const nums = bound.xpr.filter(p => p && typeof p.val === 'number').map(p => p.val)
|
|
482
|
+
if (nums.length === 3) return new Date(Date.UTC(nums[0], nums[1] - 1, nums[2]))
|
|
430
483
|
}
|
|
484
|
+
return undefined
|
|
431
485
|
}
|
|
486
|
+
return new Date(bound)
|
|
432
487
|
}
|
|
433
488
|
|
|
434
489
|
function annotatedIntRange(el, intRange) {
|
|
435
490
|
if (el['@assert.range']?.length === 2) {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
491
|
+
let from = rangeBound(el['@assert.range'][0], true)
|
|
492
|
+
let to = rangeBound(el['@assert.range'][1], false)
|
|
493
|
+
// infinity on one side: anchor a finite window to the other bound so the span stays valid
|
|
494
|
+
if (from === Infinity || from === -Infinity) from = to !== undefined && isFinite(to) ? to - 100 : intRange.from
|
|
495
|
+
if (to === Infinity || to === -Infinity) to = from !== undefined && isFinite(from) ? from + 100 : intRange.to
|
|
496
|
+
// use annotated bounds directly, so ranges outside the default [0,100] don't invert
|
|
497
|
+
if (from !== undefined) intRange.from = from
|
|
498
|
+
if (to !== undefined) intRange.to = to
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// pick a pool index that varies per association name, so multiple associations to the same
|
|
503
|
+
// target on one record (e.g. a self-referential link a<->a) land on different rows
|
|
504
|
+
function pickIndex(id, name, len) {
|
|
505
|
+
let h = 0
|
|
506
|
+
for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) | 0
|
|
507
|
+
return (((id + Math.abs(h)) % len) + len) % len
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// resolve one @assert.range bound: plain number, open bound {'=':true,val}, or infinity {'=':'_'}
|
|
511
|
+
function rangeBound(bound, isLower) {
|
|
512
|
+
if (typeof bound === 'number') return bound
|
|
513
|
+
if (bound && typeof bound === 'object') {
|
|
514
|
+
if (bound.val === '_' || bound['='] === '_') return isLower ? -Infinity : Infinity
|
|
515
|
+
const n = typeof bound.val === 'string' ? Number(bound.val) : bound.val // decimal open bounds arrive as string literals
|
|
516
|
+
if (typeof n === 'number' && !isNaN(n)) return isLower ? n + 1e-9 : n - 1e-9 // open bound: nudge inward
|
|
444
517
|
}
|
|
445
|
-
|
|
518
|
+
return undefined
|
|
446
519
|
}
|
|
447
520
|
|
|
448
521
|
const langList = ['ar', 'cs', 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja', 'ko', 'ms', 'nl', 'pl', 'pt', 'ro', 'ru', 'sv', 'th', 'tr', 'zh']
|
|
@@ -539,9 +612,9 @@ function addSemantics(csn) {
|
|
|
539
612
|
|
|
540
613
|
function randomDateInRange(dateRange) {
|
|
541
614
|
const dateFrom = dateRange.from
|
|
542
|
-
const returnDate = new Date(dateFrom.getUTCFullYear(), dateFrom.getUTCMonth(), dateFrom.getUTCDate())//
|
|
615
|
+
const returnDate = new Date(Date.UTC(dateFrom.getUTCFullYear(), dateFrom.getUTCMonth(), dateFrom.getUTCDate())) // build in UTC to match the UTC mutation below, avoiding a timezone off-by-one-day
|
|
543
616
|
const diffTime = dateRange.to.valueOf() - dateRange.from.valueOf();
|
|
544
|
-
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
|
617
|
+
const diffDays = Math.max(1, Math.ceil(diffTime / (1000 * 60 * 60 * 24))); // at least 1 day so a single-day range never yields NaN
|
|
545
618
|
const step = randomNumber() % diffDays
|
|
546
619
|
returnDate.setUTCDate(returnDate.getUTCDate() + step);
|
|
547
620
|
return returnDate
|
|
@@ -552,6 +625,8 @@ function randomDecimalInRange({ from: min, to: max }) {
|
|
|
552
625
|
}
|
|
553
626
|
|
|
554
627
|
function randomIntInRange({ from: min, to: max }) {
|
|
628
|
+
min = Math.ceil(min) // round fractional bounds inward so the result stays an integer within range
|
|
629
|
+
max = Math.floor(max)
|
|
555
630
|
const span = Math.max(0, max - min + 1)
|
|
556
631
|
return min + Math.floor(randomUnit() * span)
|
|
557
632
|
}
|