@sap/cds-dk 10.1.2 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (849) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/bin/add.js +7 -2
  3. package/bin/bind.js +0 -2
  4. package/bin/bindings.js +35 -0
  5. package/bin/build.js +11 -6
  6. package/bin/compile/index.js +1 -0
  7. package/bin/completion/index.js +10 -448
  8. package/bin/completion/scripts/cds.fish +24 -16
  9. package/bin/completion/scripts/cds.ps1 +26 -25
  10. package/bin/completion/scripts/cds.sh +22 -19
  11. package/bin/completion/scripts/cds.zsh +22 -19
  12. package/bin/deploy/index.js +1 -1
  13. package/bin/deploy/to-hana/hana.js +5 -4
  14. package/bin/env.js +0 -1
  15. package/bin/eval.js +9 -5
  16. package/bin/export.js +6 -4
  17. package/bin/help/export.md +28 -4
  18. package/bin/import.js +6 -5
  19. package/bin/inspect.js +0 -1
  20. package/bin/login.js +28 -3
  21. package/bin/repl.js +82 -26
  22. package/bin/run.js +6 -7
  23. package/bin/serve.js +6 -7
  24. package/bin/up.js +7 -2
  25. package/bin/upgrade/steps/install.js +6 -6
  26. package/bin/watch/index.js +1 -0
  27. package/lib/build/index.js +11 -7
  28. package/lib/build/plugins/featureToggles.js +2 -2
  29. package/lib/build/plugins/hana/index.js +1 -1
  30. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
  31. package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +7 -0
  32. package/lib/build/plugins/helm/files/subcharts/web-application/templates/api-rule.yaml +1 -0
  33. package/lib/build/plugins/helm/files/subcharts/web-application/templates/service-binding.yaml +4 -4
  34. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +13 -0
  35. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +7 -1
  36. package/lib/build/plugins/java/index.js +5 -1
  37. package/lib/build/plugins/nodejs/index.js +5 -1
  38. package/lib/build/util.js +4 -5
  39. package/lib/env/schemas/cds-rc.js +5 -0
  40. package/lib/import/importapi.js +2 -3
  41. package/lib/init/constants.js +1 -1
  42. package/lib/init/index.js +8 -3
  43. package/lib/init/plugin.js +1 -1
  44. package/lib/init/projectReader.js +13 -10
  45. package/lib/init/registries/mta.js +0 -6
  46. package/lib/init/template/ai/index.js +4 -4
  47. package/lib/init/template/ams/files/extensionDeveloper.dcl +6 -0
  48. package/lib/init/template/ams/files/mta.yaml.hbs +6 -0
  49. package/lib/init/template/ams/files/sidecar.package.json.hbs +5 -0
  50. package/lib/init/template/ams/index.js +42 -40
  51. package/lib/init/template/app-frontend/files/mta.yaml.hbs +2 -0
  52. package/lib/init/template/app-frontend/files/ui5.yaml.hbs +0 -4
  53. package/lib/init/template/app-frontend/index.js +29 -24
  54. package/lib/init/template/application-logging/index.js +6 -6
  55. package/lib/init/template/approuter/files/xs-app.json.hbs +22 -0
  56. package/lib/init/template/approuter/index.js +20 -13
  57. package/lib/init/template/attachments/index.js +3 -3
  58. package/lib/init/template/audit-logging/index.js +4 -4
  59. package/lib/init/template/cloud-logging/index.js +12 -6
  60. package/lib/init/template/completion/completionSetup.js +19 -6
  61. package/lib/init/template/connectivity/index.js +3 -3
  62. package/lib/init/template/data/as-csv.js +7 -4
  63. package/lib/init/template/data/as-json.js +77 -20
  64. package/lib/init/template/destination/index.js +12 -9
  65. package/lib/init/template/dynatrace/index.js +5 -5
  66. package/lib/init/template/enterprise-messaging/index.js +6 -6
  67. package/lib/init/template/enterprise-messaging-shared/index.js +4 -4
  68. package/lib/init/template/extensibility/index.js +2 -2
  69. package/lib/init/template/extension/index.js +26 -0
  70. package/lib/init/template/github-actions/index.js +3 -3
  71. package/lib/init/template/hana/files/package.json.hbs +3 -2
  72. package/lib/init/template/hana/index.js +5 -5
  73. package/lib/init/template/hana-serverless/index.js +3 -3
  74. package/lib/init/template/html5-repo/files/mta.yaml.hbs +2 -0
  75. package/lib/init/template/html5-repo/files/ui5.yaml.hbs +0 -4
  76. package/lib/init/template/html5-repo/index.js +68 -40
  77. package/lib/init/template/http/index.js +1 -1
  78. package/lib/init/template/ias/index.js +7 -7
  79. package/lib/init/template/initial/files/.gitignore.hbs +1 -0
  80. package/lib/init/template/kafka/index.js +3 -3
  81. package/lib/init/template/kyma/index.js +7 -9
  82. package/lib/init/template/malware-scanner/index.js +3 -3
  83. package/lib/init/template/mta/index.js +6 -3
  84. package/lib/init/template/multitenancy/index.js +6 -7
  85. package/lib/init/template/notifications/index.js +2 -2
  86. package/lib/init/template/portal/index.js +16 -10
  87. package/lib/init/template/postgres/index.js +5 -5
  88. package/lib/init/template/react/files/index.html.hbs +1 -1
  89. package/lib/init/template/react/files/package.json.hbs +3 -2
  90. package/lib/init/template/react/files/src/{App.jsx.hbs → App.{{jsxExtension}}.hbs} +8 -2
  91. package/lib/init/template/react/files/src/{main.jsx → main.{{jsxExtension}}.hbs} +2 -2
  92. package/lib/init/template/react/index.js +23 -4
  93. package/lib/init/template/react/typescript/src/vite-env.d.ts +1 -0
  94. package/lib/init/template/react/typescript/tsconfig.json.hbs +16 -0
  95. package/lib/init/template/redis/index.js +2 -2
  96. package/lib/init/template/side-by-side-extensibility/index.js +6 -3
  97. package/lib/init/template/typescript/files/tsconfig.json +3 -1
  98. package/lib/init/template/vue/files/index.html.hbs +1 -1
  99. package/lib/init/template/vue/files/package.json.hbs +2 -1
  100. package/lib/init/template/vue/files/src/App.vue.hbs +8 -2
  101. package/lib/init/template/vue/index.js +20 -4
  102. package/lib/init/template/vue/typescript/tsconfig.json +11 -0
  103. package/lib/init/template/workzone-standard/files/mta.yaml.hbs +2 -2
  104. package/lib/init/template/workzone-standard/index.js +29 -27
  105. package/lib/init/template/xsuaa/files/mta.yaml.hbs +1 -1
  106. package/lib/init/template/xsuaa/files/values.yaml.hbs +1 -1
  107. package/lib/init/template/xsuaa/index.js +34 -22
  108. package/lib/mtx/auth_manager.js +8 -2
  109. package/lib/mtx/browser_login.js +181 -0
  110. package/lib/mtx/params.js +6 -0
  111. package/lib/mtx/settings_manager.js +29 -4
  112. package/lib/util/cf.js +44 -8
  113. package/lib/util/fs.js +2 -2
  114. package/node_modules/@cap-js/db-service/CHANGELOG.md +10 -0
  115. package/node_modules/@cap-js/db-service/lib/cqn2pql.js +4 -0
  116. package/node_modules/@cap-js/db-service/lib/cqn2sql.js +3 -0
  117. package/node_modules/@cap-js/db-service/lib/cqn4sql.js +8 -23
  118. package/node_modules/@cap-js/db-service/lib/infer/index.js +20 -27
  119. package/node_modules/@cap-js/db-service/package.json +1 -1
  120. package/node_modules/@cap-js/openapi/cds-plugin.js +12 -0
  121. package/node_modules/@cap-js/openapi/index.js +3 -1
  122. package/node_modules/@cap-js/openapi/lib/compile/csdl2openapi.js +652 -413
  123. package/node_modules/@cap-js/openapi/lib/compile/diagram.js +16 -13
  124. package/node_modules/@cap-js/openapi/lib/compile/index.js +10 -7
  125. package/node_modules/@cap-js/openapi/lib/compile/property-util.js +51 -0
  126. package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/importOpenAPI.js +12 -9
  127. package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/index.js +4 -3
  128. package/node_modules/@cap-js/openapi/package.json +71 -3
  129. package/node_modules/@cap-js/sqlite/CHANGELOG.md +9 -0
  130. package/node_modules/@cap-js/sqlite/package.json +3 -3
  131. package/node_modules/@isaacs/fs-minipass/LICENSE +15 -0
  132. package/node_modules/@isaacs/fs-minipass/README.md +71 -0
  133. package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts +118 -0
  134. package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.d.ts.map +1 -0
  135. package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js +430 -0
  136. package/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js.map +1 -0
  137. package/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json +3 -0
  138. package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts +118 -0
  139. package/node_modules/@isaacs/fs-minipass/dist/esm/index.d.ts.map +1 -0
  140. package/node_modules/@isaacs/fs-minipass/dist/esm/index.js +420 -0
  141. package/node_modules/@isaacs/fs-minipass/dist/esm/index.js.map +1 -0
  142. package/node_modules/@isaacs/fs-minipass/dist/esm/package.json +3 -0
  143. package/node_modules/@isaacs/fs-minipass/package.json +72 -0
  144. package/node_modules/@sap/cds/CHANGELOG.md +52 -1
  145. package/node_modules/@sap/cds/_i18n/messages_ar.properties +1 -0
  146. package/node_modules/@sap/cds/_i18n/messages_bg.properties +1 -0
  147. package/node_modules/@sap/cds/_i18n/messages_cs.properties +1 -0
  148. package/node_modules/@sap/cds/_i18n/messages_da.properties +1 -0
  149. package/node_modules/@sap/cds/_i18n/messages_de.properties +1 -0
  150. package/node_modules/@sap/cds/_i18n/messages_el.properties +1 -0
  151. package/node_modules/@sap/cds/_i18n/messages_en.properties +1 -0
  152. package/node_modules/@sap/cds/_i18n/messages_es.properties +1 -0
  153. package/node_modules/@sap/cds/_i18n/messages_es_MX.properties +1 -0
  154. package/node_modules/@sap/cds/_i18n/messages_fi.properties +1 -0
  155. package/node_modules/@sap/cds/_i18n/messages_fr.properties +1 -0
  156. package/node_modules/@sap/cds/_i18n/messages_he.properties +1 -0
  157. package/node_modules/@sap/cds/_i18n/messages_hr.properties +1 -0
  158. package/node_modules/@sap/cds/_i18n/messages_hu.properties +1 -0
  159. package/node_modules/@sap/cds/_i18n/messages_it.properties +1 -0
  160. package/node_modules/@sap/cds/_i18n/messages_ja.properties +1 -0
  161. package/node_modules/@sap/cds/_i18n/messages_kk.properties +1 -0
  162. package/node_modules/@sap/cds/_i18n/messages_ko.properties +1 -0
  163. package/node_modules/@sap/cds/_i18n/messages_ms.properties +1 -0
  164. package/node_modules/@sap/cds/_i18n/messages_nl.properties +1 -0
  165. package/node_modules/@sap/cds/_i18n/messages_no.properties +1 -0
  166. package/node_modules/@sap/cds/_i18n/messages_pl.properties +1 -0
  167. package/node_modules/@sap/cds/_i18n/messages_pt.properties +1 -0
  168. package/node_modules/@sap/cds/_i18n/messages_ro.properties +1 -0
  169. package/node_modules/@sap/cds/_i18n/messages_ru.properties +1 -0
  170. package/node_modules/@sap/cds/_i18n/messages_sh.properties +1 -0
  171. package/node_modules/@sap/cds/_i18n/messages_sk.properties +1 -0
  172. package/node_modules/@sap/cds/_i18n/messages_sl.properties +1 -0
  173. package/node_modules/@sap/cds/_i18n/messages_sv.properties +1 -0
  174. package/node_modules/@sap/cds/_i18n/messages_th.properties +1 -0
  175. package/node_modules/@sap/cds/_i18n/messages_tr.properties +1 -0
  176. package/node_modules/@sap/cds/_i18n/messages_uk.properties +1 -0
  177. package/node_modules/@sap/cds/_i18n/messages_vi.properties +1 -0
  178. package/node_modules/@sap/cds/_i18n/messages_zh_CN.properties +1 -0
  179. package/node_modules/@sap/cds/_i18n/messages_zh_TW.properties +1 -0
  180. package/node_modules/@sap/cds/app/index-client.js +164 -0
  181. package/node_modules/@sap/cds/app/index.css +598 -87
  182. package/node_modules/@sap/cds/app/index.html +54 -30
  183. package/node_modules/@sap/cds/app/index.js +311 -67
  184. package/node_modules/@sap/cds/app/table.html +226 -0
  185. package/node_modules/@sap/cds/app/table.js +302 -0
  186. package/node_modules/@sap/cds/bin/serve.js +3 -2
  187. package/node_modules/@sap/cds/eslint.config.mjs +2 -0
  188. package/node_modules/@sap/cds/lib/compile/cdsc.js +7 -0
  189. package/node_modules/@sap/cds/lib/compile/for/embeddings.js +27 -0
  190. package/node_modules/@sap/cds/lib/compile/load.js +2 -2
  191. package/node_modules/@sap/cds/lib/compile/minify.js +17 -4
  192. package/node_modules/@sap/cds/lib/compile/parse.js +3 -0
  193. package/node_modules/@sap/cds/lib/compile/resolve.js +16 -14
  194. package/node_modules/@sap/cds/lib/core/classes.js +1 -0
  195. package/node_modules/@sap/cds/lib/dbs/cds-deploy.js +4 -5
  196. package/node_modules/@sap/cds/lib/env/cds-env.js +132 -70
  197. package/node_modules/@sap/cds/lib/env/cds-requires/auth-strategies.js +62 -0
  198. package/node_modules/@sap/cds/lib/env/cds-requires/databases.js +49 -0
  199. package/node_modules/@sap/cds/lib/env/cds-requires/embeddings.js +8 -0
  200. package/node_modules/@sap/cds/lib/env/cds-requires/index.js +27 -0
  201. package/node_modules/@sap/cds/lib/env/cds-requires/messaging.js +82 -0
  202. package/node_modules/@sap/cds/lib/env/cds-requires/platform.js +23 -0
  203. package/node_modules/@sap/cds/lib/env/cds-requires/queues.js +34 -0
  204. package/node_modules/@sap/cds/lib/env/cds-requires/services.js +32 -0
  205. package/node_modules/@sap/cds/lib/env/defaults.js +9 -1
  206. package/node_modules/@sap/cds/lib/i18n/files.js +4 -4
  207. package/node_modules/@sap/cds/lib/i18n/locale.js +1 -1
  208. package/node_modules/@sap/cds/lib/index.js +9 -9
  209. package/node_modules/@sap/cds/lib/log/cds-log.js +3 -3
  210. package/node_modules/@sap/cds/lib/ql/SELECT.js +2 -0
  211. package/node_modules/@sap/cds/lib/ql/UPDATE.js +1 -1
  212. package/node_modules/@sap/cds/lib/ql/cds.ql-Query.js +4 -1
  213. package/node_modules/@sap/cds/lib/ql/core/@types/cqn.d.ts +146 -0
  214. package/node_modules/@sap/cds/lib/ql/core/@types/exprs.d.ts +51 -0
  215. package/node_modules/@sap/cds/lib/ql/core/@types/index.d.ts +29 -0
  216. package/node_modules/@sap/cds/lib/ql/core/@types/package.json +7 -0
  217. package/node_modules/@sap/cds/lib/ql/core/@types/ql/delete.d.ts +8 -0
  218. package/node_modules/@sap/cds/lib/ql/core/@types/ql/insert.d.ts +19 -0
  219. package/node_modules/@sap/cds/lib/ql/core/@types/ql/select.d.ts +24 -0
  220. package/node_modules/@sap/cds/lib/ql/core/@types/ql/update.d.ts +10 -0
  221. package/node_modules/@sap/cds/lib/ql/core/@types/query.d.ts +18 -0
  222. package/node_modules/@sap/cds/lib/ql/core/cql/parser.min.js +1 -0
  223. package/node_modules/@sap/cds/lib/ql/core/lib/index.js +69 -0
  224. package/node_modules/@sap/cds/lib/ql/core/lib/ql/cache.js +34 -0
  225. package/node_modules/@sap/cds/lib/ql/core/lib/ql/call-action.js +6 -0
  226. package/node_modules/@sap/cds/lib/ql/core/lib/ql/delete.js +8 -0
  227. package/node_modules/@sap/cds/lib/ql/core/lib/ql/insert.js +26 -0
  228. package/node_modules/@sap/cds/lib/ql/core/lib/ql/select.js +22 -0
  229. package/node_modules/@sap/cds/lib/ql/core/lib/ql/update.js +26 -0
  230. package/node_modules/@sap/cds/lib/ql/core/lib/query.js +85 -0
  231. package/node_modules/@sap/cds/lib/ql/core/lib/xl/fluent.js +47 -0
  232. package/node_modules/@sap/cds/lib/ql/core/lib/xl/ttl.js +24 -0
  233. package/node_modules/@sap/cds/lib/ql/core/license +201 -0
  234. package/node_modules/@sap/cds/lib/ql/core/package.json +24 -0
  235. package/node_modules/@sap/cds/lib/ql/core/readme.md +99 -0
  236. package/node_modules/@sap/cds/lib/ql/core/upstream.json +5 -0
  237. package/node_modules/@sap/cds/lib/req/spawn.js +1 -1
  238. package/node_modules/@sap/cds/lib/srv/bindings.js +111 -115
  239. package/node_modules/@sap/cds/lib/srv/cds-connect.js +11 -10
  240. package/node_modules/@sap/cds/lib/srv/cds-serve.js +16 -7
  241. package/node_modules/@sap/cds/lib/srv/cds.Service.js +13 -7
  242. package/node_modules/@sap/cds/lib/srv/factory.js +8 -10
  243. package/node_modules/@sap/cds/lib/srv/middlewares/auth/ias-auth.js +35 -32
  244. package/node_modules/@sap/cds/lib/srv/middlewares/auth/jwt-auth.js +5 -1
  245. package/node_modules/@sap/cds/lib/srv/middlewares/auth/mocked-users.js +1 -1
  246. package/node_modules/@sap/cds/lib/srv/protocols/hcql.js +230 -79
  247. package/node_modules/@sap/cds/lib/srv/protocols/http.js +7 -3
  248. package/node_modules/@sap/cds/lib/srv/protocols/index.js +7 -2
  249. package/node_modules/@sap/cds/lib/srv/srv-dispatch.js +2 -2
  250. package/node_modules/@sap/cds/lib/utils/cds-utils.js +37 -0
  251. package/node_modules/@sap/cds/lib/utils/csv-reader.js +2 -2
  252. package/node_modules/@sap/cds/libx/_runtime/common/generic/assert.js +18 -27
  253. package/node_modules/@sap/cds/libx/_runtime/common/generic/crud.js +1 -1
  254. package/node_modules/@sap/cds/libx/_runtime/common/utils/rewriteAsterisks.js +1 -1
  255. package/node_modules/@sap/cds/libx/_runtime/fiori/lean-draft.js +121 -84
  256. package/node_modules/@sap/cds/libx/_runtime/messaging/common-utils/authorizedRequest.js +24 -1
  257. package/node_modules/@sap/cds/libx/_runtime/remote/Service.js +2 -2
  258. package/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js +3 -2
  259. package/node_modules/@sap/cds/libx/_runtime/remote/utils/query.js +11 -6
  260. package/node_modules/@sap/cds/libx/odata/middleware/create.js +4 -0
  261. package/node_modules/@sap/cds/libx/odata/middleware/metadata.js +1 -1
  262. package/node_modules/@sap/cds/libx/odata/middleware/operation.js +3 -0
  263. package/node_modules/@sap/cds/libx/odata/middleware/parse.js +9 -0
  264. package/node_modules/@sap/cds/libx/odata/middleware/read.js +6 -0
  265. package/node_modules/@sap/cds/libx/odata/middleware/update.js +5 -1
  266. package/node_modules/@sap/cds/libx/odata/parse/afterburner.js +3 -3
  267. package/node_modules/@sap/cds/libx/odata/parse/multipartToJson.js +1 -1
  268. package/node_modules/@sap/cds/libx/odata/utils/ieee754.js +20 -0
  269. package/node_modules/@sap/cds/libx/queue/api.js +1 -1
  270. package/node_modules/@sap/cds/libx/queue/index.js +3 -1
  271. package/node_modules/@sap/cds/libx/queue/processing.js +5 -0
  272. package/node_modules/@sap/cds/libx/rest/RestAdapter.js +1 -0
  273. package/node_modules/@sap/cds/package.json +2 -2
  274. package/node_modules/@sap/cds/server.js +1 -0
  275. package/node_modules/@sap/cds/srv/ucl-service.cds +1 -0
  276. package/node_modules/@sap/cds-compiler/CHANGELOG.md +83 -0
  277. package/node_modules/@sap/cds-compiler/bin/cdsse.js +1 -1
  278. package/node_modules/@sap/cds-compiler/doc/EffectiveCSN.md +3314 -0
  279. package/node_modules/@sap/cds-compiler/lib/api/main.js +9 -6
  280. package/node_modules/@sap/cds-compiler/lib/api/options.js +3 -3
  281. package/node_modules/@sap/cds-compiler/lib/{model → base}/csnUtils.js +5 -5
  282. package/node_modules/@sap/cds-compiler/lib/base/message-registry.js +54 -6
  283. package/node_modules/@sap/cds-compiler/lib/base/optionProcessor.js +4 -4
  284. package/node_modules/@sap/cds-compiler/lib/{model → base}/sortViews.js +1 -1
  285. package/node_modules/@sap/cds-compiler/lib/checks/assocOutsideService.js +1 -1
  286. package/node_modules/@sap/cds-compiler/lib/checks/checkForTypes.js +1 -1
  287. package/node_modules/@sap/cds-compiler/lib/checks/checkPathsInStoredCalcElement.js +1 -1
  288. package/node_modules/@sap/cds-compiler/lib/checks/elements.js +37 -3
  289. package/node_modules/@sap/cds-compiler/lib/checks/enricher.js +1 -1
  290. package/node_modules/@sap/cds-compiler/lib/checks/existsInForbiddenPlaces.js +1 -1
  291. package/node_modules/@sap/cds-compiler/lib/checks/hasPersistedElements.js +1 -1
  292. package/node_modules/@sap/cds-compiler/lib/checks/manyExpand.js +1 -1
  293. package/node_modules/@sap/cds-compiler/lib/checks/manyNavigations.js +1 -1
  294. package/node_modules/@sap/cds-compiler/lib/checks/onConditions.js +1 -1
  295. package/node_modules/@sap/cds-compiler/lib/checks/parameters.js +1 -1
  296. package/node_modules/@sap/cds-compiler/lib/checks/queryNoDbArtifacts.js +1 -1
  297. package/node_modules/@sap/cds-compiler/lib/checks/selectItems.js +1 -1
  298. package/node_modules/@sap/cds-compiler/lib/checks/structuredAnnoExpressions.js +1 -1
  299. package/node_modules/@sap/cds-compiler/lib/checks/typeParameters.js +1 -1
  300. package/node_modules/@sap/cds-compiler/lib/checks/types.js +1 -1
  301. package/node_modules/@sap/cds-compiler/lib/checks/validator.js +1 -1
  302. package/node_modules/@sap/cds-compiler/lib/compiler/assert-consistency.js +20 -12
  303. package/node_modules/@sap/cds-compiler/lib/compiler/builtins.js +9 -4
  304. package/node_modules/@sap/cds-compiler/lib/compiler/checks.js +50 -0
  305. package/node_modules/@sap/cds-compiler/lib/compiler/define.js +303 -323
  306. package/node_modules/@sap/cds-compiler/lib/compiler/dictionaries.js +5 -0
  307. package/node_modules/@sap/cds-compiler/lib/compiler/extend.js +1015 -1177
  308. package/node_modules/@sap/cds-compiler/lib/compiler/generate.js +55 -42
  309. package/node_modules/@sap/cds-compiler/lib/compiler/populate.js +74 -45
  310. package/node_modules/@sap/cds-compiler/lib/compiler/propagator.js +1 -0
  311. package/node_modules/@sap/cds-compiler/lib/compiler/resolve.js +6 -4
  312. package/node_modules/@sap/cds-compiler/lib/compiler/shared.js +30 -49
  313. package/node_modules/@sap/cds-compiler/lib/compiler/utils.js +32 -18
  314. package/node_modules/@sap/cds-compiler/lib/edm/annotations/edmJson.js +3 -3
  315. package/node_modules/@sap/cds-compiler/lib/edm/annotations/genericTranslation.js +2 -2
  316. package/node_modules/@sap/cds-compiler/lib/edm/annotations/preprocessAnnotations.js +2 -3
  317. package/node_modules/@sap/cds-compiler/lib/edm/csn2edm.js +1 -1
  318. package/node_modules/@sap/cds-compiler/lib/edm/edm.js +6 -7
  319. package/node_modules/@sap/cds-compiler/lib/edm/edmAnnoPreprocessor.js +1 -1
  320. package/node_modules/@sap/cds-compiler/lib/edm/edmInboundChecks.js +1 -1
  321. package/node_modules/@sap/cds-compiler/lib/edm/edmPreprocessor.js +1 -1
  322. package/node_modules/@sap/cds-compiler/lib/edm/edmUtils.js +12 -7
  323. package/node_modules/@sap/cds-compiler/lib/gen/CdlGrammar.checksum +1 -1
  324. package/node_modules/@sap/cds-compiler/lib/gen/CdlParser.js +15 -15
  325. package/node_modules/@sap/cds-compiler/lib/gen/Dictionary.json +7 -0
  326. package/node_modules/@sap/cds-compiler/lib/json/from-csn.js +30 -30
  327. package/node_modules/@sap/cds-compiler/lib/json/to-csn.js +2 -1
  328. package/node_modules/@sap/cds-compiler/lib/main.js +4 -1
  329. package/node_modules/@sap/cds-compiler/lib/parsers/AstBuildingParser.js +42 -15
  330. package/node_modules/@sap/cds-compiler/lib/render/DuplicateChecker.js +37 -11
  331. package/node_modules/@sap/cds-compiler/lib/render/manageConstraints.js +1 -1
  332. package/node_modules/@sap/cds-compiler/lib/render/toCdl.js +11 -6
  333. package/node_modules/@sap/cds-compiler/lib/render/toRename.js +1 -1
  334. package/node_modules/@sap/cds-compiler/lib/render/toSql.js +74 -24
  335. package/node_modules/@sap/cds-compiler/lib/render/utils/common.js +1 -1
  336. package/node_modules/@sap/cds-compiler/lib/render/utils/operators.js +81 -0
  337. package/node_modules/@sap/cds-compiler/lib/render/utils/sql.js +17 -10
  338. package/node_modules/@sap/cds-compiler/lib/transform/db/assertUnique.js +1 -1
  339. package/node_modules/@sap/cds-compiler/lib/transform/db/associations.js +3 -4
  340. package/node_modules/@sap/cds-compiler/lib/transform/db/assocsToQueries/transformExists.js +1 -1
  341. package/node_modules/@sap/cds-compiler/lib/transform/db/backlinks.js +2 -2
  342. package/node_modules/@sap/cds-compiler/lib/transform/db/cdsPersistence.js +1 -1
  343. package/node_modules/@sap/cds-compiler/lib/transform/db/constraints.js +6 -5
  344. package/node_modules/@sap/cds-compiler/lib/transform/db/expansion.js +7 -1
  345. package/node_modules/@sap/cds-compiler/lib/transform/db/flattening.js +2 -2
  346. package/node_modules/@sap/cds-compiler/lib/{modelCompare/compare.js → transform/db/migration/diffModels.js} +5 -5
  347. package/node_modules/@sap/cds-compiler/lib/{modelCompare/utils/filter.js → transform/db/migration/filterDiff.js} +2 -2
  348. package/node_modules/@sap/cds-compiler/lib/transform/db/processSqlServices.js +1 -1
  349. package/node_modules/@sap/cds-compiler/lib/transform/db/rewriteCalculatedElements.js +1 -1
  350. package/node_modules/@sap/cds-compiler/lib/transform/db/temporal.js +1 -1
  351. package/node_modules/@sap/cds-compiler/lib/transform/db/views.js +2 -6
  352. package/node_modules/@sap/cds-compiler/lib/transform/draft/db.js +1 -1
  353. package/node_modules/@sap/cds-compiler/lib/transform/draft/odata.js +1 -1
  354. package/node_modules/@sap/cds-compiler/lib/transform/effective/annotations.js +1 -1
  355. package/node_modules/@sap/cds-compiler/lib/transform/effective/associations.js +1 -1
  356. package/node_modules/@sap/cds-compiler/lib/transform/effective/flattening.js +1 -1
  357. package/node_modules/@sap/cds-compiler/lib/transform/effective/main.js +3 -2
  358. package/node_modules/@sap/cds-compiler/lib/transform/effective/misc.js +2 -1
  359. package/node_modules/@sap/cds-compiler/lib/transform/effective/queries.js +1 -1
  360. package/node_modules/@sap/cds-compiler/lib/transform/effective/types.js +1 -1
  361. package/node_modules/@sap/cds-compiler/lib/transform/forOdata.js +1 -1
  362. package/node_modules/@sap/cds-compiler/lib/transform/forRelationalDB.js +9 -4
  363. package/node_modules/@sap/cds-compiler/lib/transform/localized.js +1 -1
  364. package/node_modules/@sap/cds-compiler/lib/transform/odata/adaptAnnotationRefs.js +5 -11
  365. package/node_modules/@sap/cds-compiler/lib/transform/odata/createForeignKeys.js +1 -1
  366. package/node_modules/@sap/cds-compiler/lib/transform/odata/flattening.js +4 -4
  367. package/node_modules/@sap/cds-compiler/lib/transform/odata/foreignKeyRefsInXprAnnos.js +5 -3
  368. package/node_modules/@sap/cds-compiler/lib/transform/odata/toFinalBaseType.js +29 -5
  369. package/node_modules/@sap/cds-compiler/lib/transform/odata/typesExposure.js +13 -3
  370. package/node_modules/@sap/cds-compiler/lib/transform/odata/utils.js +9 -0
  371. package/node_modules/@sap/cds-compiler/lib/transform/transformUtils.js +2 -2
  372. package/node_modules/@sap/cds-compiler/lib/transform/translateAssocsToJoins.js +1 -1
  373. package/node_modules/@sap/cds-compiler/lib/transform/tupleExpansion.js +1 -1
  374. package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/coreComputed.js +1 -1
  375. package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/universalCsnEnricher.js +1 -1
  376. package/node_modules/@sap/cds-compiler/lib/transform/universalCsn/utils.js +1 -1
  377. package/node_modules/@sap/cds-compiler/package.json +1 -1
  378. package/node_modules/@sap/cds-mtxs/CHANGELOG.md +47 -0
  379. package/node_modules/@sap/cds-mtxs/bin/cds-mtx-migrate.js +4 -6
  380. package/node_modules/@sap/cds-mtxs/bin/cds-mtx.js +5 -4
  381. package/node_modules/@sap/cds-mtxs/cds-plugin.js +38 -2
  382. package/node_modules/@sap/cds-mtxs/db/t0.cds +7 -0
  383. package/node_modules/@sap/cds-mtxs/lib/utils.js +129 -20
  384. package/node_modules/@sap/cds-mtxs/package.json +15 -14
  385. package/node_modules/@sap/cds-mtxs/srv/cf/abstract-provisioning-service.js +13 -12
  386. package/node_modules/@sap/cds-mtxs/srv/cf/saas-provisioning-service.cds +1 -0
  387. package/node_modules/@sap/cds-mtxs/srv/cf/sms-provisioning-service.cds +1 -0
  388. package/node_modules/@sap/cds-mtxs/srv/extensibility/compat/update.js +5 -2
  389. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/config.js +1 -2
  390. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/csv-allowlist.js +64 -0
  391. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/index.js +4 -2
  392. package/node_modules/@sap/cds-mtxs/srv/extensibility/linter/protected-namespace.js +67 -5
  393. package/node_modules/@sap/cds-mtxs/srv/extensibility-service.js +179 -15
  394. package/node_modules/@sap/cds-mtxs/srv/jobs-service.js +12 -3
  395. package/node_modules/@sap/cds-mtxs/srv/plugins/common.js +33 -12
  396. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/ctnr-mgr-base.js +24 -6
  397. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-ctnr-mgr.js +3 -1
  398. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/hdi-native.js +752 -0
  399. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/serverless.js +17 -20
  400. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr-v2.js +511 -0
  401. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/srv-mgr.js +11 -4
  402. package/node_modules/@sap/cds-mtxs/srv/plugins/hana/tms.js +8 -0
  403. package/node_modules/@sap/cds-mtxs/srv/plugins/hana.js +27 -18
  404. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker-pool.js +1 -1
  405. package/node_modules/@sap/cds-mtxs/srv/worker/job-worker.js +1 -1
  406. package/node_modules/chownr/LICENSE.md +63 -0
  407. package/node_modules/chownr/README.md +3 -0
  408. package/node_modules/chownr/dist/commonjs/index.d.ts +3 -0
  409. package/node_modules/chownr/dist/commonjs/index.d.ts.map +1 -0
  410. package/node_modules/chownr/dist/commonjs/index.js +93 -0
  411. package/node_modules/chownr/dist/commonjs/index.js.map +1 -0
  412. package/node_modules/chownr/dist/commonjs/package.json +3 -0
  413. package/node_modules/chownr/dist/esm/index.d.ts +3 -0
  414. package/node_modules/chownr/dist/esm/index.d.ts.map +1 -0
  415. package/node_modules/chownr/dist/esm/index.js +85 -0
  416. package/node_modules/chownr/dist/esm/index.js.map +1 -0
  417. package/node_modules/chownr/dist/esm/package.json +3 -0
  418. package/node_modules/chownr/package.json +69 -0
  419. package/node_modules/content-disposition/README.md +105 -35
  420. package/node_modules/content-disposition/dist/index.d.ts +72 -0
  421. package/node_modules/content-disposition/dist/index.js +388 -0
  422. package/node_modules/content-disposition/dist/index.js.map +1 -0
  423. package/node_modules/content-disposition/package.json +31 -19
  424. package/node_modules/content-type/README.md +34 -57
  425. package/node_modules/content-type/package.json +35 -25
  426. package/node_modules/express/Readme.md +15 -9
  427. package/node_modules/express/lib/application.js +2 -2
  428. package/node_modules/express/lib/request.js +32 -19
  429. package/node_modules/express/lib/response.js +27 -30
  430. package/node_modules/express/package.json +10 -10
  431. package/node_modules/handlebars/bin/handlebars +1 -1
  432. package/node_modules/handlebars/dist/amd/handlebars/base.js +2 -2
  433. package/node_modules/handlebars/dist/amd/handlebars/compiler/base.js +2 -59
  434. package/node_modules/handlebars/dist/amd/handlebars/compiler/code-gen.js +68 -5
  435. package/node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js +160 -19
  436. package/node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js +23 -7
  437. package/node_modules/handlebars/dist/amd/handlebars/compiler/node-types.js +12 -0
  438. package/node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js +26 -7
  439. package/node_modules/handlebars/dist/amd/handlebars/compiler/whitespace-control.js +9 -4
  440. package/node_modules/handlebars/dist/amd/handlebars/exception.js +8 -4
  441. package/node_modules/handlebars/dist/amd/handlebars/helpers/each.js +40 -14
  442. package/node_modules/handlebars/dist/amd/handlebars/internal/proto-access.js +21 -1
  443. package/node_modules/handlebars/dist/amd/handlebars/runtime.js +24 -4
  444. package/node_modules/handlebars/dist/amd/handlebars/utils.js +4 -3
  445. package/node_modules/handlebars/dist/amd/precompiler.js +13 -7
  446. package/node_modules/handlebars/dist/cjs/handlebars/base.js +2 -2
  447. package/node_modules/handlebars/dist/cjs/handlebars/compiler/base.js +1 -60
  448. package/node_modules/handlebars/dist/cjs/handlebars/compiler/code-gen.js +64 -4
  449. package/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js +161 -18
  450. package/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js +23 -7
  451. package/node_modules/handlebars/dist/cjs/handlebars/compiler/node-types.js +10 -0
  452. package/node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js +29 -6
  453. package/node_modules/handlebars/dist/cjs/handlebars/compiler/whitespace-control.js +9 -4
  454. package/node_modules/handlebars/dist/cjs/handlebars/exception.js +8 -4
  455. package/node_modules/handlebars/dist/cjs/handlebars/helpers/each.js +40 -14
  456. package/node_modules/handlebars/dist/cjs/handlebars/internal/proto-access.js +21 -1
  457. package/node_modules/handlebars/dist/cjs/handlebars/runtime.js +24 -4
  458. package/node_modules/handlebars/dist/cjs/handlebars/utils.js +4 -3
  459. package/node_modules/handlebars/dist/cjs/precompiler.js +14 -6
  460. package/node_modules/handlebars/dist/handlebars.amd.js +401 -130
  461. package/node_modules/handlebars/dist/handlebars.amd.min.js +4 -4
  462. package/node_modules/handlebars/dist/handlebars.js +396 -125
  463. package/node_modules/handlebars/dist/handlebars.min.js +4 -4
  464. package/node_modules/handlebars/dist/handlebars.runtime.amd.js +100 -29
  465. package/node_modules/handlebars/dist/handlebars.runtime.amd.min.js +2 -2
  466. package/node_modules/handlebars/dist/handlebars.runtime.js +94 -23
  467. package/node_modules/handlebars/dist/handlebars.runtime.min.js +2 -2
  468. package/node_modules/handlebars/lib/handlebars/base.js +1 -1
  469. package/node_modules/handlebars/lib/handlebars/compiler/base.js +0 -67
  470. package/node_modules/handlebars/lib/handlebars/compiler/code-gen.js +65 -11
  471. package/node_modules/handlebars/lib/handlebars/compiler/compiler.js +164 -23
  472. package/node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js +23 -7
  473. package/node_modules/handlebars/lib/handlebars/compiler/node-types.js +24 -0
  474. package/node_modules/handlebars/lib/handlebars/compiler/visitor.js +29 -5
  475. package/node_modules/handlebars/lib/handlebars/compiler/whitespace-control.js +16 -5
  476. package/node_modules/handlebars/lib/handlebars/exception.js +7 -3
  477. package/node_modules/handlebars/lib/handlebars/helpers/each.js +39 -16
  478. package/node_modules/handlebars/lib/handlebars/internal/proto-access.js +22 -0
  479. package/node_modules/handlebars/lib/handlebars/runtime.js +36 -4
  480. package/node_modules/handlebars/lib/handlebars/utils.js +3 -2
  481. package/node_modules/handlebars/lib/precompiler.js +14 -5
  482. package/node_modules/handlebars/package.json +2 -2
  483. package/node_modules/handlebars/release-notes.md +20 -1
  484. package/node_modules/handlebars/types/index.d.ts +8 -0
  485. package/node_modules/hdb/cfg/VERSION +1 -1
  486. package/node_modules/hdb/lib/Client.js +6 -2
  487. package/node_modules/hdb/lib/protocol/ClientInfo.js +28 -15
  488. package/node_modules/hdb/lib/protocol/Connection.js +30 -3
  489. package/node_modules/hdb/lib/protocol/Writer.js +2 -2
  490. package/node_modules/hdb/lib/protocol/common/ConnectOption.js +2 -0
  491. package/node_modules/hdb/lib/protocol/common/ConnectOptionFlagSet1.js +18 -0
  492. package/node_modules/hdb/lib/protocol/common/ConnectOptionType.js +2 -0
  493. package/node_modules/hdb/lib/protocol/common/Constants.js +1 -0
  494. package/node_modules/hdb/lib/protocol/common/MessageType.js +3 -2
  495. package/node_modules/hdb/lib/protocol/common/PartKind.js +2 -1
  496. package/node_modules/hdb/lib/protocol/common/index.js +1 -0
  497. package/node_modules/hdb/lib/protocol/data/TextList.js +25 -17
  498. package/node_modules/hdb/lib/protocol/data/index.js +1 -0
  499. package/node_modules/hdb/lib/protocol/part/ConnectOptions.js +7 -0
  500. package/node_modules/hdb/lib/protocol/request/index.js +7 -0
  501. package/node_modules/hdb/package.json +1 -2
  502. package/node_modules/livereload-js/.github/workflows/main.yml +4 -4
  503. package/node_modules/livereload-js/README.md +3 -3
  504. package/node_modules/livereload-js/dist/livereload.js +839 -2742
  505. package/node_modules/livereload-js/dist/livereload.min.js +1 -1
  506. package/node_modules/livereload-js/package.json +11 -11
  507. package/node_modules/minipass/LICENSE.md +55 -0
  508. package/node_modules/minipass/README.md +825 -0
  509. package/node_modules/minipass/dist/commonjs/index.d.ts +545 -0
  510. package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -0
  511. package/node_modules/minipass/dist/commonjs/index.js +1038 -0
  512. package/node_modules/minipass/dist/commonjs/index.js.map +1 -0
  513. package/node_modules/minipass/dist/commonjs/package.json +3 -0
  514. package/node_modules/minipass/dist/esm/index.d.ts +545 -0
  515. package/node_modules/minipass/dist/esm/index.d.ts.map +1 -0
  516. package/node_modules/minipass/dist/esm/index.js +1020 -0
  517. package/node_modules/minipass/dist/esm/index.js.map +1 -0
  518. package/node_modules/minipass/dist/esm/package.json +3 -0
  519. package/node_modules/minipass/package.json +77 -0
  520. package/node_modules/minizlib/LICENSE +26 -0
  521. package/node_modules/minizlib/README.md +64 -0
  522. package/node_modules/minizlib/dist/commonjs/constants.d.ts +2 -0
  523. package/node_modules/minizlib/dist/commonjs/constants.d.ts.map +1 -0
  524. package/node_modules/minizlib/dist/commonjs/constants.js +123 -0
  525. package/node_modules/minizlib/dist/commonjs/constants.js.map +1 -0
  526. package/node_modules/minizlib/dist/commonjs/index.d.ts +99 -0
  527. package/node_modules/minizlib/dist/commonjs/index.d.ts.map +1 -0
  528. package/node_modules/minizlib/dist/commonjs/index.js +416 -0
  529. package/node_modules/minizlib/dist/commonjs/index.js.map +1 -0
  530. package/node_modules/minizlib/dist/commonjs/package.json +3 -0
  531. package/node_modules/minizlib/dist/esm/constants.d.ts +2 -0
  532. package/node_modules/minizlib/dist/esm/constants.d.ts.map +1 -0
  533. package/node_modules/minizlib/dist/esm/constants.js +117 -0
  534. package/node_modules/minizlib/dist/esm/constants.js.map +1 -0
  535. package/node_modules/minizlib/dist/esm/index.d.ts +99 -0
  536. package/node_modules/minizlib/dist/esm/index.d.ts.map +1 -0
  537. package/node_modules/minizlib/dist/esm/index.js +363 -0
  538. package/node_modules/minizlib/dist/esm/index.js.map +1 -0
  539. package/node_modules/minizlib/dist/esm/package.json +3 -0
  540. package/node_modules/minizlib/package.json +80 -0
  541. package/node_modules/qs/.github/THREAT_MODEL.md +4 -2
  542. package/node_modules/qs/CHANGELOG.md +38 -14
  543. package/node_modules/qs/README.md +31 -3
  544. package/node_modules/qs/dist/qs.js +20 -20
  545. package/node_modules/qs/lib/parse.js +94 -4
  546. package/node_modules/qs/lib/stringify.js +4 -4
  547. package/node_modules/qs/lib/utils.js +130 -6
  548. package/node_modules/qs/package.json +4 -4
  549. package/node_modules/qs/test/parse.js +174 -0
  550. package/node_modules/qs/test/stringify.js +263 -33
  551. package/node_modules/qs/test/utils.js +184 -0
  552. package/node_modules/tar/LICENSE.md +55 -0
  553. package/node_modules/tar/README.md +1233 -0
  554. package/node_modules/tar/dist/commonjs/create.d.ts +3 -0
  555. package/node_modules/tar/dist/commonjs/create.d.ts.map +1 -0
  556. package/node_modules/tar/dist/commonjs/create.js +82 -0
  557. package/node_modules/tar/dist/commonjs/create.js.map +1 -0
  558. package/node_modules/tar/dist/commonjs/cwd-error.d.ts +8 -0
  559. package/node_modules/tar/dist/commonjs/cwd-error.d.ts.map +1 -0
  560. package/node_modules/tar/dist/commonjs/cwd-error.js +18 -0
  561. package/node_modules/tar/dist/commonjs/cwd-error.js.map +1 -0
  562. package/node_modules/tar/dist/commonjs/extract.d.ts +3 -0
  563. package/node_modules/tar/dist/commonjs/extract.d.ts.map +1 -0
  564. package/node_modules/tar/dist/commonjs/extract.js +88 -0
  565. package/node_modules/tar/dist/commonjs/extract.js.map +1 -0
  566. package/node_modules/tar/dist/commonjs/get-write-flag.d.ts +2 -0
  567. package/node_modules/tar/dist/commonjs/get-write-flag.d.ts.map +1 -0
  568. package/node_modules/tar/dist/commonjs/get-write-flag.js +32 -0
  569. package/node_modules/tar/dist/commonjs/get-write-flag.js.map +1 -0
  570. package/node_modules/tar/dist/commonjs/header.d.ts +53 -0
  571. package/node_modules/tar/dist/commonjs/header.d.ts.map +1 -0
  572. package/node_modules/tar/dist/commonjs/header.js +348 -0
  573. package/node_modules/tar/dist/commonjs/header.js.map +1 -0
  574. package/node_modules/tar/dist/commonjs/index.d.ts +20 -0
  575. package/node_modules/tar/dist/commonjs/index.d.ts.map +1 -0
  576. package/node_modules/tar/dist/commonjs/index.js +64 -0
  577. package/node_modules/tar/dist/commonjs/index.js.map +1 -0
  578. package/node_modules/tar/dist/commonjs/index.min.js +4 -0
  579. package/node_modules/tar/dist/commonjs/index.min.js.map +7 -0
  580. package/node_modules/tar/dist/commonjs/large-numbers.d.ts +3 -0
  581. package/node_modules/tar/dist/commonjs/large-numbers.d.ts.map +1 -0
  582. package/node_modules/tar/dist/commonjs/large-numbers.js +99 -0
  583. package/node_modules/tar/dist/commonjs/large-numbers.js.map +1 -0
  584. package/node_modules/tar/dist/commonjs/list.d.ts +7 -0
  585. package/node_modules/tar/dist/commonjs/list.d.ts.map +1 -0
  586. package/node_modules/tar/dist/commonjs/list.js +153 -0
  587. package/node_modules/tar/dist/commonjs/list.js.map +1 -0
  588. package/node_modules/tar/dist/commonjs/make-command.d.ts +49 -0
  589. package/node_modules/tar/dist/commonjs/make-command.d.ts.map +1 -0
  590. package/node_modules/tar/dist/commonjs/make-command.js +52 -0
  591. package/node_modules/tar/dist/commonjs/make-command.js.map +1 -0
  592. package/node_modules/tar/dist/commonjs/mkdir.d.ts +25 -0
  593. package/node_modules/tar/dist/commonjs/mkdir.d.ts.map +1 -0
  594. package/node_modules/tar/dist/commonjs/mkdir.js +187 -0
  595. package/node_modules/tar/dist/commonjs/mkdir.js.map +1 -0
  596. package/node_modules/tar/dist/commonjs/mode-fix.d.ts +2 -0
  597. package/node_modules/tar/dist/commonjs/mode-fix.d.ts.map +1 -0
  598. package/node_modules/tar/dist/commonjs/mode-fix.js +29 -0
  599. package/node_modules/tar/dist/commonjs/mode-fix.js.map +1 -0
  600. package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts +2 -0
  601. package/node_modules/tar/dist/commonjs/normalize-unicode.d.ts.map +1 -0
  602. package/node_modules/tar/dist/commonjs/normalize-unicode.js +38 -0
  603. package/node_modules/tar/dist/commonjs/normalize-unicode.js.map +1 -0
  604. package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts +2 -0
  605. package/node_modules/tar/dist/commonjs/normalize-windows-path.d.ts.map +1 -0
  606. package/node_modules/tar/dist/commonjs/normalize-windows-path.js +12 -0
  607. package/node_modules/tar/dist/commonjs/normalize-windows-path.js.map +1 -0
  608. package/node_modules/tar/dist/commonjs/options.d.ts +604 -0
  609. package/node_modules/tar/dist/commonjs/options.d.ts.map +1 -0
  610. package/node_modules/tar/dist/commonjs/options.js +66 -0
  611. package/node_modules/tar/dist/commonjs/options.js.map +1 -0
  612. package/node_modules/tar/dist/commonjs/pack.d.ts +105 -0
  613. package/node_modules/tar/dist/commonjs/pack.d.ts.map +1 -0
  614. package/node_modules/tar/dist/commonjs/pack.js +544 -0
  615. package/node_modules/tar/dist/commonjs/pack.js.map +1 -0
  616. package/node_modules/tar/dist/commonjs/package.json +3 -0
  617. package/node_modules/tar/dist/commonjs/parse.d.ts +92 -0
  618. package/node_modules/tar/dist/commonjs/parse.d.ts.map +1 -0
  619. package/node_modules/tar/dist/commonjs/parse.js +655 -0
  620. package/node_modules/tar/dist/commonjs/parse.js.map +1 -0
  621. package/node_modules/tar/dist/commonjs/path-reservations.d.ts +11 -0
  622. package/node_modules/tar/dist/commonjs/path-reservations.d.ts.map +1 -0
  623. package/node_modules/tar/dist/commonjs/path-reservations.js +170 -0
  624. package/node_modules/tar/dist/commonjs/path-reservations.js.map +1 -0
  625. package/node_modules/tar/dist/commonjs/pax.d.ts +26 -0
  626. package/node_modules/tar/dist/commonjs/pax.d.ts.map +1 -0
  627. package/node_modules/tar/dist/commonjs/pax.js +182 -0
  628. package/node_modules/tar/dist/commonjs/pax.js.map +1 -0
  629. package/node_modules/tar/dist/commonjs/process-umask.d.ts +2 -0
  630. package/node_modules/tar/dist/commonjs/process-umask.d.ts.map +1 -0
  631. package/node_modules/tar/dist/commonjs/process-umask.js +7 -0
  632. package/node_modules/tar/dist/commonjs/process-umask.js.map +1 -0
  633. package/node_modules/tar/dist/commonjs/read-entry.d.ts +36 -0
  634. package/node_modules/tar/dist/commonjs/read-entry.d.ts.map +1 -0
  635. package/node_modules/tar/dist/commonjs/read-entry.js +136 -0
  636. package/node_modules/tar/dist/commonjs/read-entry.js.map +1 -0
  637. package/node_modules/tar/dist/commonjs/replace.d.ts +2 -0
  638. package/node_modules/tar/dist/commonjs/replace.d.ts.map +1 -0
  639. package/node_modules/tar/dist/commonjs/replace.js +227 -0
  640. package/node_modules/tar/dist/commonjs/replace.js.map +1 -0
  641. package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts +2 -0
  642. package/node_modules/tar/dist/commonjs/strip-absolute-path.d.ts.map +1 -0
  643. package/node_modules/tar/dist/commonjs/strip-absolute-path.js +29 -0
  644. package/node_modules/tar/dist/commonjs/strip-absolute-path.js.map +1 -0
  645. package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts +2 -0
  646. package/node_modules/tar/dist/commonjs/strip-trailing-slashes.d.ts.map +1 -0
  647. package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js +18 -0
  648. package/node_modules/tar/dist/commonjs/strip-trailing-slashes.js.map +1 -0
  649. package/node_modules/tar/dist/commonjs/symlink-error.d.ts +9 -0
  650. package/node_modules/tar/dist/commonjs/symlink-error.d.ts.map +1 -0
  651. package/node_modules/tar/dist/commonjs/symlink-error.js +19 -0
  652. package/node_modules/tar/dist/commonjs/symlink-error.js.map +1 -0
  653. package/node_modules/tar/dist/commonjs/types.d.ts +16 -0
  654. package/node_modules/tar/dist/commonjs/types.d.ts.map +1 -0
  655. package/node_modules/tar/dist/commonjs/types.js +70 -0
  656. package/node_modules/tar/dist/commonjs/types.js.map +1 -0
  657. package/node_modules/tar/dist/commonjs/unpack.d.ts +101 -0
  658. package/node_modules/tar/dist/commonjs/unpack.d.ts.map +1 -0
  659. package/node_modules/tar/dist/commonjs/unpack.js +932 -0
  660. package/node_modules/tar/dist/commonjs/unpack.js.map +1 -0
  661. package/node_modules/tar/dist/commonjs/update.d.ts +2 -0
  662. package/node_modules/tar/dist/commonjs/update.d.ts.map +1 -0
  663. package/node_modules/tar/dist/commonjs/update.js +33 -0
  664. package/node_modules/tar/dist/commonjs/update.js.map +1 -0
  665. package/node_modules/tar/dist/commonjs/warn-method.d.ts +24 -0
  666. package/node_modules/tar/dist/commonjs/warn-method.d.ts.map +1 -0
  667. package/node_modules/tar/dist/commonjs/warn-method.js +31 -0
  668. package/node_modules/tar/dist/commonjs/warn-method.js.map +1 -0
  669. package/node_modules/tar/dist/commonjs/winchars.d.ts +3 -0
  670. package/node_modules/tar/dist/commonjs/winchars.d.ts.map +1 -0
  671. package/node_modules/tar/dist/commonjs/winchars.js +14 -0
  672. package/node_modules/tar/dist/commonjs/winchars.js.map +1 -0
  673. package/node_modules/tar/dist/commonjs/write-entry.d.ts +129 -0
  674. package/node_modules/tar/dist/commonjs/write-entry.d.ts.map +1 -0
  675. package/node_modules/tar/dist/commonjs/write-entry.js +698 -0
  676. package/node_modules/tar/dist/commonjs/write-entry.js.map +1 -0
  677. package/node_modules/tar/dist/esm/create.d.ts +3 -0
  678. package/node_modules/tar/dist/esm/create.d.ts.map +1 -0
  679. package/node_modules/tar/dist/esm/create.js +76 -0
  680. package/node_modules/tar/dist/esm/create.js.map +1 -0
  681. package/node_modules/tar/dist/esm/cwd-error.d.ts +8 -0
  682. package/node_modules/tar/dist/esm/cwd-error.d.ts.map +1 -0
  683. package/node_modules/tar/dist/esm/cwd-error.js +14 -0
  684. package/node_modules/tar/dist/esm/cwd-error.js.map +1 -0
  685. package/node_modules/tar/dist/esm/extract.d.ts +3 -0
  686. package/node_modules/tar/dist/esm/extract.d.ts.map +1 -0
  687. package/node_modules/tar/dist/esm/extract.js +49 -0
  688. package/node_modules/tar/dist/esm/extract.js.map +1 -0
  689. package/node_modules/tar/dist/esm/get-write-flag.d.ts +2 -0
  690. package/node_modules/tar/dist/esm/get-write-flag.d.ts.map +1 -0
  691. package/node_modules/tar/dist/esm/get-write-flag.js +26 -0
  692. package/node_modules/tar/dist/esm/get-write-flag.js.map +1 -0
  693. package/node_modules/tar/dist/esm/header.d.ts +53 -0
  694. package/node_modules/tar/dist/esm/header.d.ts.map +1 -0
  695. package/node_modules/tar/dist/esm/header.js +311 -0
  696. package/node_modules/tar/dist/esm/header.js.map +1 -0
  697. package/node_modules/tar/dist/esm/index.d.ts +20 -0
  698. package/node_modules/tar/dist/esm/index.d.ts.map +1 -0
  699. package/node_modules/tar/dist/esm/index.js +20 -0
  700. package/node_modules/tar/dist/esm/index.js.map +1 -0
  701. package/node_modules/tar/dist/esm/index.min.js +4 -0
  702. package/node_modules/tar/dist/esm/index.min.js.map +7 -0
  703. package/node_modules/tar/dist/esm/large-numbers.d.ts +3 -0
  704. package/node_modules/tar/dist/esm/large-numbers.d.ts.map +1 -0
  705. package/node_modules/tar/dist/esm/large-numbers.js +94 -0
  706. package/node_modules/tar/dist/esm/large-numbers.js.map +1 -0
  707. package/node_modules/tar/dist/esm/list.d.ts +7 -0
  708. package/node_modules/tar/dist/esm/list.d.ts.map +1 -0
  709. package/node_modules/tar/dist/esm/list.js +113 -0
  710. package/node_modules/tar/dist/esm/list.js.map +1 -0
  711. package/node_modules/tar/dist/esm/make-command.d.ts +49 -0
  712. package/node_modules/tar/dist/esm/make-command.d.ts.map +1 -0
  713. package/node_modules/tar/dist/esm/make-command.js +48 -0
  714. package/node_modules/tar/dist/esm/make-command.js.map +1 -0
  715. package/node_modules/tar/dist/esm/mkdir.d.ts +25 -0
  716. package/node_modules/tar/dist/esm/mkdir.d.ts.map +1 -0
  717. package/node_modules/tar/dist/esm/mkdir.js +179 -0
  718. package/node_modules/tar/dist/esm/mkdir.js.map +1 -0
  719. package/node_modules/tar/dist/esm/mode-fix.d.ts +2 -0
  720. package/node_modules/tar/dist/esm/mode-fix.d.ts.map +1 -0
  721. package/node_modules/tar/dist/esm/mode-fix.js +25 -0
  722. package/node_modules/tar/dist/esm/mode-fix.js.map +1 -0
  723. package/node_modules/tar/dist/esm/normalize-unicode.d.ts +2 -0
  724. package/node_modules/tar/dist/esm/normalize-unicode.d.ts.map +1 -0
  725. package/node_modules/tar/dist/esm/normalize-unicode.js +34 -0
  726. package/node_modules/tar/dist/esm/normalize-unicode.js.map +1 -0
  727. package/node_modules/tar/dist/esm/normalize-windows-path.d.ts +2 -0
  728. package/node_modules/tar/dist/esm/normalize-windows-path.d.ts.map +1 -0
  729. package/node_modules/tar/dist/esm/normalize-windows-path.js +9 -0
  730. package/node_modules/tar/dist/esm/normalize-windows-path.js.map +1 -0
  731. package/node_modules/tar/dist/esm/options.d.ts +604 -0
  732. package/node_modules/tar/dist/esm/options.d.ts.map +1 -0
  733. package/node_modules/tar/dist/esm/options.js +54 -0
  734. package/node_modules/tar/dist/esm/options.js.map +1 -0
  735. package/node_modules/tar/dist/esm/pack.d.ts +105 -0
  736. package/node_modules/tar/dist/esm/pack.d.ts.map +1 -0
  737. package/node_modules/tar/dist/esm/pack.js +502 -0
  738. package/node_modules/tar/dist/esm/pack.js.map +1 -0
  739. package/node_modules/tar/dist/esm/package.json +3 -0
  740. package/node_modules/tar/dist/esm/parse.d.ts +92 -0
  741. package/node_modules/tar/dist/esm/parse.d.ts.map +1 -0
  742. package/node_modules/tar/dist/esm/parse.js +651 -0
  743. package/node_modules/tar/dist/esm/parse.js.map +1 -0
  744. package/node_modules/tar/dist/esm/path-reservations.d.ts +11 -0
  745. package/node_modules/tar/dist/esm/path-reservations.d.ts.map +1 -0
  746. package/node_modules/tar/dist/esm/path-reservations.js +166 -0
  747. package/node_modules/tar/dist/esm/path-reservations.js.map +1 -0
  748. package/node_modules/tar/dist/esm/pax.d.ts +26 -0
  749. package/node_modules/tar/dist/esm/pax.d.ts.map +1 -0
  750. package/node_modules/tar/dist/esm/pax.js +178 -0
  751. package/node_modules/tar/dist/esm/pax.js.map +1 -0
  752. package/node_modules/tar/dist/esm/process-umask.d.ts +2 -0
  753. package/node_modules/tar/dist/esm/process-umask.d.ts.map +1 -0
  754. package/node_modules/tar/dist/esm/process-umask.js +3 -0
  755. package/node_modules/tar/dist/esm/process-umask.js.map +1 -0
  756. package/node_modules/tar/dist/esm/read-entry.d.ts +36 -0
  757. package/node_modules/tar/dist/esm/read-entry.d.ts.map +1 -0
  758. package/node_modules/tar/dist/esm/read-entry.js +132 -0
  759. package/node_modules/tar/dist/esm/read-entry.js.map +1 -0
  760. package/node_modules/tar/dist/esm/replace.d.ts +2 -0
  761. package/node_modules/tar/dist/esm/replace.d.ts.map +1 -0
  762. package/node_modules/tar/dist/esm/replace.js +221 -0
  763. package/node_modules/tar/dist/esm/replace.js.map +1 -0
  764. package/node_modules/tar/dist/esm/strip-absolute-path.d.ts +2 -0
  765. package/node_modules/tar/dist/esm/strip-absolute-path.d.ts.map +1 -0
  766. package/node_modules/tar/dist/esm/strip-absolute-path.js +25 -0
  767. package/node_modules/tar/dist/esm/strip-absolute-path.js.map +1 -0
  768. package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts +2 -0
  769. package/node_modules/tar/dist/esm/strip-trailing-slashes.d.ts.map +1 -0
  770. package/node_modules/tar/dist/esm/strip-trailing-slashes.js +14 -0
  771. package/node_modules/tar/dist/esm/strip-trailing-slashes.js.map +1 -0
  772. package/node_modules/tar/dist/esm/symlink-error.d.ts +9 -0
  773. package/node_modules/tar/dist/esm/symlink-error.d.ts.map +1 -0
  774. package/node_modules/tar/dist/esm/symlink-error.js +15 -0
  775. package/node_modules/tar/dist/esm/symlink-error.js.map +1 -0
  776. package/node_modules/tar/dist/esm/types.d.ts +16 -0
  777. package/node_modules/tar/dist/esm/types.d.ts.map +1 -0
  778. package/node_modules/tar/dist/esm/types.js +65 -0
  779. package/node_modules/tar/dist/esm/types.js.map +1 -0
  780. package/node_modules/tar/dist/esm/unpack.d.ts +101 -0
  781. package/node_modules/tar/dist/esm/unpack.d.ts.map +1 -0
  782. package/node_modules/tar/dist/esm/unpack.js +891 -0
  783. package/node_modules/tar/dist/esm/unpack.js.map +1 -0
  784. package/node_modules/tar/dist/esm/update.d.ts +2 -0
  785. package/node_modules/tar/dist/esm/update.d.ts.map +1 -0
  786. package/node_modules/tar/dist/esm/update.js +30 -0
  787. package/node_modules/tar/dist/esm/update.js.map +1 -0
  788. package/node_modules/tar/dist/esm/warn-method.d.ts +24 -0
  789. package/node_modules/tar/dist/esm/warn-method.d.ts.map +1 -0
  790. package/node_modules/tar/dist/esm/warn-method.js +27 -0
  791. package/node_modules/tar/dist/esm/warn-method.js.map +1 -0
  792. package/node_modules/tar/dist/esm/winchars.d.ts +3 -0
  793. package/node_modules/tar/dist/esm/winchars.d.ts.map +1 -0
  794. package/node_modules/tar/dist/esm/winchars.js +9 -0
  795. package/node_modules/tar/dist/esm/winchars.js.map +1 -0
  796. package/node_modules/tar/dist/esm/write-entry.d.ts +129 -0
  797. package/node_modules/tar/dist/esm/write-entry.d.ts.map +1 -0
  798. package/node_modules/tar/dist/esm/write-entry.js +656 -0
  799. package/node_modules/tar/dist/esm/write-entry.js.map +1 -0
  800. package/node_modules/tar/package.json +298 -0
  801. package/node_modules/ws/lib/websocket.js +17 -3
  802. package/node_modules/ws/package.json +1 -1
  803. package/node_modules/yallist/LICENSE.md +63 -0
  804. package/node_modules/yallist/README.md +205 -0
  805. package/node_modules/yallist/dist/commonjs/index.d.ts +39 -0
  806. package/node_modules/yallist/dist/commonjs/index.d.ts.map +1 -0
  807. package/node_modules/yallist/dist/commonjs/index.js +384 -0
  808. package/node_modules/yallist/dist/commonjs/index.js.map +1 -0
  809. package/node_modules/yallist/dist/commonjs/package.json +3 -0
  810. package/node_modules/yallist/dist/esm/index.d.ts +39 -0
  811. package/node_modules/yallist/dist/esm/index.d.ts.map +1 -0
  812. package/node_modules/yallist/dist/esm/index.js +379 -0
  813. package/node_modules/yallist/dist/esm/index.js.map +1 -0
  814. package/node_modules/yallist/dist/esm/package.json +3 -0
  815. package/node_modules/yallist/package.json +68 -0
  816. package/package.json +7 -1
  817. package/bin/completion/templates/cds-tmpl.fish +0 -65
  818. package/bin/completion/templates/cds-tmpl.ps1 +0 -217
  819. package/bin/completion/templates/cds-tmpl.sh +0 -93
  820. package/bin/completion/templates/cds-tmpl.zsh +0 -74
  821. package/node_modules/@cap-js/db-service/lib/recursion-guard.js +0 -40
  822. package/node_modules/@sap/cds/lib/env/cds-requires.js +0 -327
  823. package/node_modules/@sap/cds-mtxs/srv/bootstrap.cds +0 -2
  824. package/node_modules/@sap/cds-mtxs/srv/bootstrap.js +0 -33
  825. package/node_modules/body-parser/node_modules/content-type/LICENSE +0 -22
  826. package/node_modules/body-parser/node_modules/content-type/README.md +0 -71
  827. package/node_modules/body-parser/node_modules/content-type/package.json +0 -52
  828. package/node_modules/content-disposition/index.js +0 -536
  829. package/node_modules/content-type/HISTORY.md +0 -29
  830. package/node_modules/content-type/index.js +0 -225
  831. package/node_modules/negotiator/node_modules/content-type/LICENSE +0 -22
  832. package/node_modules/negotiator/node_modules/content-type/README.md +0 -71
  833. package/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +0 -46
  834. package/node_modules/negotiator/node_modules/content-type/dist/index.js +0 -176
  835. package/node_modules/negotiator/node_modules/content-type/dist/index.js.map +0 -1
  836. package/node_modules/negotiator/node_modules/content-type/package.json +0 -52
  837. package/node_modules/type-is/node_modules/content-type/LICENSE +0 -22
  838. package/node_modules/type-is/node_modules/content-type/README.md +0 -71
  839. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +0 -46
  840. package/node_modules/type-is/node_modules/content-type/dist/index.js +0 -176
  841. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +0 -1
  842. package/node_modules/type-is/node_modules/content-type/package.json +0 -52
  843. /package/lib/init/template/react/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +0 -0
  844. /package/lib/init/template/vue/files/src/{main.js → main.{{extension}}.hbs} +0 -0
  845. /package/lib/init/template/vue/files/{vite.config.js.hbs → vite.config.{{extension}}.hbs} +0 -0
  846. /package/{lib/import/openapi → node_modules/@cap-js/openapi/lib/import}/utilities.js +0 -0
  847. /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.d.ts +0 -0
  848. /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js +0 -0
  849. /package/node_modules/{body-parser/node_modules/content-type → content-type}/dist/index.js.map +0 -0
@@ -5,9 +5,12 @@ const cds = require('@sap/cds');
5
5
  const { CSDLMeta, nameParts, isIdentifier } = require('./csdl');
6
6
  const { camelCaseToWords: splitName } = require('./string-util');
7
7
  const { Diagram } = require('./diagram')
8
+ const propertyUtil = require('./property-util');
8
9
  const pluralize = require('pluralize')
9
10
  const DEBUG = cds.debug('openapi'); // Initialize cds.debug with the 'openapi'
10
11
 
12
+ const isODataProtocol = (protocol) => !protocol || protocol.startsWith('odata');
13
+
11
14
  //TODO
12
15
  // - Core.Example for complex types
13
16
  // - reduce number of loops over schemas
@@ -84,10 +87,44 @@ const ER_ANNOTATIONS = Object.freeze(
84
87
  '@EntityRelationship.referencesWithConstantIds': 'x-entity-relationship-references-with-constant-ids'
85
88
  });
86
89
 
90
+ /**
91
+ * Base Schema Objects for Edm primitive types whose mapping does not depend on
92
+ * any facet of the model element (no MaxLength, Precision, Pattern, etc.).
93
+ * Callers must clone before mutating, since the schema is augmented in place.
94
+ */
95
+ const CONSTANT_EDM_SCHEMAS = Object.freeze({
96
+ 'Edm.AnnotationPath': { type: 'string' },
97
+ 'Edm.meta.modelElementPath': { type: 'string' },
98
+ 'Edm.NavigationPropertyPath': { type: 'string' },
99
+ 'Edm.PropertyPath': { type: 'string' },
100
+ 'Edm.Boolean': { type: 'boolean' },
101
+ 'Edm.Byte': { type: 'integer', format: 'uint8' },
102
+ 'Edm.Date': { type: 'string', format: 'date', example: '2017-04-13' },
103
+ 'Edm.Double': { anyOf: [{ type: 'number', format: 'double' }, { type: 'string' }], example: 3.14 },
104
+ 'Edm.Duration': { type: 'string', format: 'duration', example: 'P4DT15H51M04S' },
105
+ 'Edm.Guid': { type: 'string', format: 'uuid', example: '01234567-89ab-cdef-0123-456789abcdef' },
106
+ 'Edm.Int16': { type: 'integer', format: 'int16' },
107
+ 'Edm.Int32': { type: 'integer', format: 'int32' },
108
+ 'Edm.Int64': { anyOf: [{ type: 'integer', format: 'int64' }, { type: 'string' }], example: "42" },
109
+ 'Edm.PrimitiveType': { anyOf: [{ type: 'boolean' }, { type: 'number' }, { type: 'string' }] },
110
+ 'Edm.SByte': { type: 'integer', format: 'int8' },
111
+ 'Edm.Single': { anyOf: [{ type: 'number', format: 'float' }, { type: 'string' }], example: 3.14 },
112
+ 'Edm.TimeOfDay': { type: 'string', format: 'time', example: '15:51:04' },
113
+ });
114
+
115
+ /**
116
+ * Normalize the diagram option, treating the string "false" as disabled
117
+ * @param {*} diagram Raw diagram option value
118
+ * @return {boolean} Whether diagrams are enabled
119
+ */
120
+ function normalizeDiagramFlag(diagram) {
121
+ return /** @type {unknown} */(diagram) !== "false" && !!diagram;
122
+ }
123
+
87
124
  /**
88
125
  * Construct an OpenAPI description from a CSDL document
89
126
  * @param {CSDL} csdl CSDL document
90
- * @param {{ url?: string, servers?: object, odataVersion?: string, scheme?: string, host?: string, basePath?: string, diagram?: boolean, maxLevels?: number, shortActionPaths?: boolean }} options Optional parameters
127
+ * @param {{ url?: string, servers?: object, odataVersion?: string, protocol?: string, scheme?: string, host?: string, basePath?: string, diagram?: boolean, maxLevels?: number, shortActionPaths?: boolean }} options Optional parameters
91
128
  * @return {*} OpenAPI description
92
129
  */
93
130
  module.exports.csdl2openapi = function (
@@ -96,6 +133,7 @@ module.exports.csdl2openapi = function (
96
133
  url: serviceRoot,
97
134
  servers: serversObject,
98
135
  odataVersion,
136
+ protocol,
99
137
  scheme = 'https',
100
138
  host = 'localhost',
101
139
  basePath = '/service-root',
@@ -104,11 +142,12 @@ module.exports.csdl2openapi = function (
104
142
  shortActionPaths = false
105
143
  } = {}
106
144
  ) {
107
- diagram = /** @type {unknown} */(diagram) !== "false" && !!diagram;
145
+ diagram = normalizeDiagramFlag(diagram);
108
146
  // as preProcess below mutates the csdl, copy it before, to avoid side-effects on the caller side
109
147
  csdl = structuredClone(csdl)
110
148
  csdl.$Version = odataVersion ? odataVersion : '4.01'
111
149
  const meta = new CSDLMeta(csdl)
150
+ const { isNavBackReference, isNavWritable, isScalarReadOnly, isScalarWritable, isMandatoryField, isDeltaSupported } = propertyUtil(meta);
112
151
  serviceRoot = serviceRoot ?? (`${scheme}://${host}${basePath}`);
113
152
  const queryOptionPrefix = csdl.$Version <= '4.01' ? '$' : '';
114
153
  const typesToInline = {}; // filled in schema() and used in inlineTypes()
@@ -117,21 +156,7 @@ module.exports.csdl2openapi = function (
117
156
  const requiredSchemas = { list: [], used: {} };
118
157
 
119
158
  const entityContainer = csdl.$EntityContainer ? meta.modelElement(csdl.$EntityContainer) : {};
120
- if (csdl.$EntityContainer) {
121
- const serviceName = nameParts(csdl.$EntityContainer).qualifier;
122
- Object.keys(entityContainer).forEach(element => {
123
- if (entityContainer[element].$Type) {
124
- const fullTypeName = entityContainer[element].$Type;
125
- const type = fullTypeName.startsWith(`${serviceName}.`)
126
- ? fullTypeName.substring(serviceName.length + 1)
127
- : nameParts(fullTypeName).name;
128
- if ((csdl[serviceName]?.[type]?.['@cds.autoexpose'] || csdl[serviceName]?.[type]?.['@cds.autoexposed'])
129
- && (!entityContainer[type] || type.endsWith('_texts'))) {
130
- entityContainer[element]['$cds.autoexpose'] = true;
131
- }
132
- }
133
- });
134
- }
159
+ applyAutoExposeFlags(entityContainer);
135
160
 
136
161
  const keyAsSegment = entityContainer ? entityContainer[meta.voc.Capabilities.KeyAsSegmentSupported] : {};
137
162
 
@@ -147,13 +172,51 @@ module.exports.csdl2openapi = function (
147
172
  components: getComponents(csdl, entityContainer)
148
173
  };
149
174
 
150
- const externalDocs = getExternalDoc(csdl);
151
- if (externalDocs && Object.keys(externalDocs).length > 0) {
152
- openapi.externalDocs = externalDocs;
175
+ applyRootDocExtensions(openapi);
176
+
177
+ /**
178
+ * Remove servers and tags that only apply when an entity container is present
179
+ * @param {*} openapi OpenAPI document to augment in place
180
+ */
181
+ function removeContainerlessArtifacts(openapi) {
182
+ if (csdl.$EntityContainer) return;
183
+ // explicit cast required as .servers and .tags are not declared as optional
184
+ delete /**@type{any}*/(openapi).servers;
185
+ delete /**@type{any}*/(openapi).tags;
153
186
  }
154
- const extensions = getExtensions(csdl, 'root');
155
- if (extensions && Object.keys(extensions).length > 0) {
156
- Object.assign(openapi, extensions);
187
+
188
+ /**
189
+ * Merge external docs and root-level @OpenAPI.Extensions into the OpenAPI document
190
+ * @param {*} openapi OpenAPI document to augment in place
191
+ */
192
+ function applyRootDocExtensions(openapi) {
193
+ const externalDocs = getExternalDoc(csdl);
194
+ if (externalDocs && Object.keys(externalDocs).length > 0) openapi.externalDocs = externalDocs;
195
+ const extensions = getExtensions(csdl, 'root');
196
+ if (extensions && Object.keys(extensions).length > 0) Object.assign(openapi, extensions);
197
+ }
198
+
199
+ /**
200
+ * Copy @cds.autoexpose(d) annotations from service types onto the entity container elements
201
+ * @param {*} entityContainer Entity container to augment in place
202
+ */
203
+ function applyAutoExposeFlags(entityContainer) {
204
+ if (!csdl.$EntityContainer) return;
205
+ const serviceName = nameParts(csdl.$EntityContainer).qualifier;
206
+ Object.keys(entityContainer).forEach(element => {
207
+ const fullTypeName = entityContainer[element].$Type;
208
+ if (!fullTypeName) return;
209
+ const type = fullTypeName.startsWith(`${serviceName}.`)
210
+ ? fullTypeName.substring(serviceName.length + 1)
211
+ : nameParts(fullTypeName).name;
212
+ const serviceType = csdl[serviceName]?.[type];
213
+ if (serviceType?.['@cds.autoexpose'] || serviceType?.['@cds.autoexposed']) {
214
+ entityContainer[element]['$cds.autoexpose'] = true;
215
+ }
216
+ if (serviceType?.['@cds.autoexposed'] && !serviceType?.['@cds.autoexpose']) {
217
+ entityContainer[element]['$cds.autoexposed'] = true;
218
+ }
219
+ });
157
220
  }
158
221
 
159
222
  // function to read @OpenAPI.Extensions and get them in the generated openAPI document
@@ -252,11 +315,7 @@ module.exports.csdl2openapi = function (
252
315
  node[keys[keys.length - 1]] = value;
253
316
  }
254
317
 
255
- if (!csdl.$EntityContainer) {
256
- // explicit cast required as .servers and .tags are not declared as optional
257
- delete /**@type{any}*/(openapi).servers;
258
- delete /**@type{any}*/(openapi).tags;
259
- }
318
+ removeContainerlessArtifacts(openapi);
260
319
 
261
320
  security(openapi, entityContainer);
262
321
 
@@ -381,7 +440,7 @@ module.exports.csdl2openapi = function (
381
440
  Object.keys(container)
382
441
  .filter(name => isIdentifier(name) && container[name].$Type)
383
442
  .forEach(child => {
384
- if (child.endsWith('_texts') && container[child]['$cds.autoexpose']) {
443
+ if (container[child]['$cds.autoexposed']) {
385
444
  return;
386
445
  }
387
446
  const type = meta.modelElement(container[child].$Type) || {};
@@ -404,9 +463,10 @@ module.exports.csdl2openapi = function (
404
463
  * @returns {T}
405
464
  */
406
465
  function normaliseTag(tag) {
407
- const normalise = s => s
408
- .replaceAll('_', ' ')
409
- .replace(/([a-z])([A-Z])/g, '$1 $2'); // "camelCase" to "camel Case"
466
+ const normalise = s => /{i18n>([^}]+)}/.test(s)
467
+ ? s
468
+ : s.replaceAll('_', ' ')
469
+ .replace(/([a-z])([A-Z])/g, '$1 $2'); // "camelCase" to "camel Case"
410
470
  if (typeof tag === 'string') {
411
471
  tag = normalise(tag);
412
472
  } else {
@@ -426,7 +486,7 @@ module.exports.csdl2openapi = function (
426
486
  const resources = Object.keys(container).filter(name => isIdentifier(name));
427
487
  resources.forEach(name => {
428
488
  const child = container[name];
429
- if (name.endsWith('_texts') && child['$cds.autoexpose']) {
489
+ if (child['$cds.autoexposed']) {
430
490
  return;
431
491
  }
432
492
  if (child.$Type) {
@@ -454,7 +514,7 @@ module.exports.csdl2openapi = function (
454
514
  DEBUG?.(`Unrecognized entity container child: ${name}`);
455
515
  }
456
516
  })
457
- if (resources.length > 0) pathItemBatch(paths, container);
517
+ if (resources.length > 0 && isODataProtocol(protocol)) pathItemBatch(paths, container);
458
518
  return Object.keys(paths).sort().reduce((p, c) => (p[c] = paths[c], p), {});
459
519
  }
460
520
 
@@ -754,62 +814,114 @@ module.exports.csdl2openapi = function (
754
814
  const targetRestrictions = target?.[meta.voc.Capabilities.ReadRestrictions];
755
815
  const readRestrictions = restrictions.ReadRestrictions || targetRestrictions || {};
756
816
  const readByKeyRestrictions = readRestrictions.ReadByKeyRestrictions;
757
- let readable = true;
758
- const countRestrictions = target && (target[meta.voc.Capabilities.CountRestrictions]?.Countable === false);
817
+ if (!isReadable({ byKey, readRestrictions, readByKeyRestrictions })) return;
818
+
819
+ const collection = !byKey && element.$Collection;
820
+ const operation = buildReadOperation({
821
+ element, name, sourceName, targetName, target, level, restrictions,
822
+ byKey, targetRestrictions, readRestrictions, readByKeyRestrictions, collection
823
+ });
824
+ customParameters(operation, byKey ? readByKeyRestrictions || readRestrictions : readRestrictions);
825
+
826
+ if (collection) {
827
+ optionTop(operation.parameters, target, restrictions);
828
+ optionSkip(operation.parameters, target, restrictions);
829
+ if (csdl.$Version >= '4.0') optionSearch(operation.parameters, target, restrictions);
830
+ optionFilter(operation.parameters, target, restrictions);
831
+ optionCount(operation.parameters, target);
832
+ optionOrderBy(operation.parameters, element, target, restrictions);
833
+ }
834
+
835
+ optionSelect(operation.parameters, element, target, restrictions);
836
+ optionExpand(operation.parameters, element, target, nonExpandable);
837
+
838
+ pathItem.get = operation;
839
+ }
840
+
841
+ /**
842
+ * Determine whether a read operation is allowed by the read restrictions
843
+ * @param {object} options
844
+ * @param {boolean} options.byKey Read by key
845
+ * @param {*} options.readRestrictions Read restrictions
846
+ * @param {*} options.readByKeyRestrictions Read-by-key restrictions
847
+ * @returns {boolean} Whether the resource is readable
848
+ */
849
+ function isReadable({ byKey, readRestrictions, readByKeyRestrictions }) {
759
850
  if (byKey && readByKeyRestrictions && readByKeyRestrictions.Readable !== undefined)
760
- readable = readByKeyRestrictions.Readable;
761
- else if (readRestrictions.Readable !== undefined)
762
- readable = readRestrictions.Readable;
851
+ return readByKeyRestrictions.Readable;
852
+ if (readRestrictions.Readable !== undefined)
853
+ return readRestrictions.Readable;
854
+ return true;
855
+ }
763
856
 
764
- if (readable) {
765
- let descriptions = (level == 0 ? targetRestrictions : restrictions.ReadRestrictions) || {};
766
- if (byKey) descriptions = descriptions.ReadByKeyRestrictions || {};
767
- const lname = splitName(name);
768
- const collection = !byKey && element.$Collection;
769
- const operation = {
770
- summary: descriptions.Description || operationSummary({
771
- operation: 'Retrieves',
772
- name,
773
- sourceName,
774
- level,
775
- collection: element.$Collection,
776
- byKey
777
- }),
778
- tags: [normaliseTag(sourceName)],
779
- parameters: [],
780
- responses: response({
781
- code: 200,
782
- description: `Retrieved ${byKey ? pluralize.singular(lname) : lname}`,
783
- type: { $Type: element.$Type, $Collection: collection },
784
- errors: byKey ? readByKeyRestrictions?.ErrorResponses : readRestrictions?.ErrorResponses,
785
- isCount: !countRestrictions
786
- })
787
- };
788
- const deltaSupported = element[meta.voc.Capabilities.ChangeTracking] && element[meta.voc.Capabilities.ChangeTracking].Supported;
789
- if (!byKey && deltaSupported) {
790
- // @ts-expect-error - set above
791
- operation.responses[200].content['application/json'].schema.properties['@odata.deltaLink'] = {
792
- type: 'string',
793
- example: `${basePath}/${name}?$deltatoken=opaque server-generated token for fetching the delta`
794
- }
795
- }
796
- if (descriptions.LongDescription) operation.description = descriptions.LongDescription;
797
- if (target && sourceName != targetName) operation.tags.push(normaliseTag(targetName));
798
- customParameters(operation, byKey ? readByKeyRestrictions || readRestrictions : readRestrictions);
799
-
800
- if (collection) {
801
- optionTop(operation.parameters, target, restrictions);
802
- optionSkip(operation.parameters, target, restrictions);
803
- if (csdl.$Version >= '4.0') optionSearch(operation.parameters, target, restrictions);
804
- optionFilter(operation.parameters, target, restrictions);
805
- optionCount(operation.parameters, target);
806
- optionOrderBy(operation.parameters, element, target, restrictions);
807
- }
857
+ /**
858
+ * Construct the read Operation Object
859
+ * @param {object} options
860
+ * @param {*} options.element Model element of navigation segment
861
+ * @param {string} options.name Name of navigation segment
862
+ * @param {string} options.sourceName Name of path source
863
+ * @param {string} options.targetName Name of path target
864
+ * @param {null | TargetRestrictions} options.target Target container child of path
865
+ * @param {number} options.level Number of navigation segments so far
866
+ * @param {*} options.restrictions Navigation property restrictions of navigation segment
867
+ * @param {boolean} options.byKey Read by key
868
+ * @param {*} options.targetRestrictions Read restrictions of the target
869
+ * @param {*} options.readRestrictions Effective read restrictions
870
+ * @param {*} options.readByKeyRestrictions Read-by-key restrictions
871
+ * @param {*} options.collection Whether the response is a collection
872
+ * @returns {*} Operation Object
873
+ */
874
+ function buildReadOperation({ element, name, sourceName, targetName, target, level, restrictions, byKey, targetRestrictions, readRestrictions, readByKeyRestrictions, collection }) {
875
+ const descriptions = readDescriptions({ level, targetRestrictions, restrictions, byKey });
876
+ const lname = splitName(name);
877
+ const summary = descriptions.Description || operationSummary({
878
+ operation: 'Retrieves', name, sourceName, level, collection: element.$Collection, byKey
879
+ });
880
+ const errors = byKey ? readByKeyRestrictions?.ErrorResponses : readRestrictions?.ErrorResponses;
881
+ const isCount = !(target && target[meta.voc.Capabilities.CountRestrictions]?.Countable === false);
882
+ const operation = {
883
+ summary,
884
+ tags: [normaliseTag(sourceName)],
885
+ parameters: [],
886
+ responses: response({
887
+ code: 200,
888
+ description: `Retrieved ${byKey ? pluralize.singular(lname) : lname}`,
889
+ type: { $Type: element.$Type, $Collection: collection },
890
+ errors,
891
+ isCount
892
+ })
893
+ };
894
+ if (!byKey) addDeltaLink(operation, element, name);
895
+ if (descriptions.LongDescription) operation.description = descriptions.LongDescription;
896
+ if (target && sourceName != targetName) operation.tags.push(normaliseTag(targetName));
897
+ return operation;
898
+ }
808
899
 
809
- optionSelect(operation.parameters, element, target, restrictions);
810
- optionExpand(operation.parameters, element, target, nonExpandable);
900
+ /**
901
+ * Resolve the description-carrying restrictions for a read operation
902
+ * @param {object} options
903
+ * @param {number} options.level Number of navigation segments so far
904
+ * @param {*} options.targetRestrictions Read restrictions of the target
905
+ * @param {*} options.restrictions Navigation property restrictions of navigation segment
906
+ * @param {boolean} options.byKey Read by key
907
+ * @returns {*} Restrictions object carrying Description / LongDescription
908
+ */
909
+ function readDescriptions({ level, targetRestrictions, restrictions, byKey }) {
910
+ const descriptions = (level == 0 ? targetRestrictions : restrictions.ReadRestrictions) || {};
911
+ return byKey ? descriptions.ReadByKeyRestrictions || {} : descriptions;
912
+ }
811
913
 
812
- pathItem.get = operation;
914
+ /**
915
+ * Add the @odata.deltaLink property to a collection read response if delta is supported
916
+ * @param {*} operation Operation Object to augment
917
+ * @param {*} element Model element of navigation segment
918
+ * @param {string} name Name of navigation segment
919
+ */
920
+ function addDeltaLink(operation, element, name) {
921
+ if (!isDeltaSupported(element)) return;
922
+ operation.responses[200].content['application/json'].schema.properties['@odata.deltaLink'] = {
923
+ type: 'string',
924
+ example: `${basePath}/${name}?$deltatoken=opaque server-generated token for fetching the delta`
813
925
  }
814
926
  }
815
927
 
@@ -1311,7 +1423,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1311
1423
  */
1312
1424
  function pathItemsForMediaStream({ paths, prefix, prefixParameters, type, name, sourceName }) {
1313
1425
  if (type.$HasStream) {
1314
- const mediaTypes = type[meta.voc.Core.AcceptableMediaTypes]?.map(t => t['$EnumMember'] ?? t) ?? [];
1426
+ const mediaTypes = type[meta.voc.Core.AcceptableMediaTypes]?.map(t => t.$EnumMember ?? t) ?? [];
1315
1427
  const contentTypes = mediaTypes.length > 0 ? mediaTypes : ['*/*'];
1316
1428
  const mediaContent = Object.fromEntries(contentTypes.map(ct => [ct, { schema: { type: 'string', format: 'binary' } }]));
1317
1429
  const lname = splitName(name);
@@ -1741,63 +1853,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1741
1853
  const implicitAliases = csdl.$Version > '4.0' || parameters.some(p => p[meta.voc.Core.OptionalParameter]);
1742
1854
 
1743
1855
  parameters.forEach(p => {
1744
- const description = getDescriptionWithFallback(p);
1745
- /** @type {Parameter} */
1746
- const param = {
1747
- ...(description && { description }),
1748
- required: implicitAliases ? !p[meta.voc.Core.OptionalParameter] : true
1749
- };
1750
- const type = meta.modelElement(p.$Type || 'Edm.String');
1751
- // TODO: check whether parameter or type definition of Edm.Stream is annotated with JSON.Schema
1752
- if (p.$Collection || p.$Type == 'Edm.Stream'
1753
- || type && ['ComplexType', 'EntityType'].includes(type.$Kind)
1754
- || type && type.$UnderlyingType == 'Edm.Stream') {
1755
- param.in = 'query';
1756
- if (
1757
- implicitAliases &&
1758
- csdl.$Version !== '2.0' &&
1759
- SYSTEM_QUERY_OPTIONS.includes(p.$Name.toLowerCase())
1760
- ) {
1761
- param.name = `@${p.$Name}`;
1762
- } else if (implicitAliases) {
1763
- param.name = p.$Name;
1764
- } else {
1765
- pathSegments.push(`${p.$Name}=@${p.$Name}`);
1766
- param.name = `@${p.$Name}`;
1767
- }
1768
- param.schema = { type: 'string' };
1769
- if (param.description) param.description += ' \n'; else param.description = '';
1770
- param.description += `This is ${
1771
- p.$Collection ? 'a ' : ''
1772
- }URL-encoded JSON ${
1773
- p.$Collection ? 'array with items ' : ''
1774
- }of type ${
1775
- meta.namespaceQualifiedName(p.$Type ?? 'Edm.String')
1776
- }, see [Complex and Collection Literals](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_ComplexandCollectionLiterals)`;
1777
- param.example = p.$Collection ? '[]' : '{}';
1778
- } else {
1779
- if (implicitAliases) {
1780
- param.in = 'query';
1781
- } else {
1782
- pathSegments.push(`${p.$Name}={${p.$Name}}`);
1783
- param.in = 'path';
1784
- }
1785
- if (
1786
- implicitAliases &&
1787
- csdl.$Version !== '2.0' &&
1788
- SYSTEM_QUERY_OPTIONS.includes(p.$Name.toLowerCase())
1789
- )
1790
- param.name = `@${p.$Name}`;
1791
- else
1792
- param.name = p.$Name;
1793
- if (!p.$Type || p.$Type === "Edm.String" || (type && (!type.$Type || type.$Type === "Edm.String"))) {
1794
- if (param.description) param.description += ' \n';
1795
- else param.description = '';
1796
- param.description += "String value needs to be enclosed in single quotes";
1797
- }
1798
- param.schema = getSchema(p, '', true, true);
1799
- }
1800
- params.push(param);
1856
+ params.push(functionParameter(p, { implicitAliases, pathSegments }));
1801
1857
  });
1802
1858
 
1803
1859
  const pathParameters = implicitAliases ? '' : `(${pathSegments.join(',')})`;
@@ -1814,14 +1870,125 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1814
1870
  }),
1815
1871
  }
1816
1872
  };
1873
+ applyOperationDetails(pathItem.get, overload, functionImport);
1874
+ paths[prefix + pathParameters] = pathItem;
1875
+ }
1876
+
1877
+ /**
1878
+ * Apply extensions, long description and custom parameters to a function operation
1879
+ * @param {*} operation Operation Object to augment
1880
+ * @param {*} overload Function overload
1881
+ * @param {*} functionImport Function import
1882
+ */
1883
+ function applyOperationDetails(operation, overload, functionImport) {
1817
1884
  const functionExtension = getExtensions(overload, 'operation');
1818
1885
  if (Object.keys(functionExtension).length > 0) {
1819
- Object.assign(pathItem.get, functionExtension);
1886
+ Object.assign(operation, functionExtension);
1820
1887
  }
1821
1888
  const iDescription = functionImport[meta.voc.Core.LongDescription] || overload[meta.voc.Core.LongDescription];
1822
- if (iDescription) pathItem.get.description = iDescription;
1823
- customParameters(pathItem.get, overload[meta.voc.Capabilities.OperationRestrictions] || {});
1824
- paths[prefix + pathParameters] = pathItem;
1889
+ if (iDescription) operation.description = iDescription;
1890
+ customParameters(operation, overload[meta.voc.Capabilities.OperationRestrictions] || {});
1891
+ }
1892
+
1893
+ /**
1894
+ * Construct a Parameter Object for a function parameter
1895
+ * @param {*} p Function parameter
1896
+ * @param {object} options
1897
+ * @param {boolean} options.implicitAliases Whether parameter aliases are used implicitly
1898
+ * @param {Array} options.pathSegments Path segments to augment for inline parameters
1899
+ * @returns {Parameter} Parameter Object
1900
+ */
1901
+ function functionParameter(p, { implicitAliases, pathSegments }) {
1902
+ const description = getDescriptionWithFallback(p);
1903
+ /** @type {Parameter} */
1904
+ const param = {
1905
+ ...(description && { description }),
1906
+ required: implicitAliases ? !p[meta.voc.Core.OptionalParameter] : true
1907
+ };
1908
+ const type = meta.modelElement(p.$Type || 'Edm.String');
1909
+ // TODO: check whether parameter or type definition of Edm.Stream is annotated with JSON.Schema
1910
+ if (isStructuredFunctionParam(p, type))
1911
+ addStructuredFunctionParam(param, p, { implicitAliases, pathSegments });
1912
+ else
1913
+ addSimpleFunctionParam(param, p, type, { implicitAliases, pathSegments });
1914
+ return param;
1915
+ }
1916
+
1917
+ /**
1918
+ * Whether a function parameter must be passed as a URL-encoded JSON query option
1919
+ * @param {*} p Function parameter
1920
+ * @param {*} type Resolved model element of the parameter type
1921
+ * @returns {boolean} Whether the parameter is structured
1922
+ */
1923
+ function isStructuredFunctionParam(p, type) {
1924
+ return p.$Collection || p.$Type == 'Edm.Stream'
1925
+ || (type && ['ComplexType', 'EntityType'].includes(type.$Kind))
1926
+ || (type && type.$UnderlyingType == 'Edm.Stream');
1927
+ }
1928
+
1929
+ /**
1930
+ * Resolve the parameter name, aliasing system query options with a leading '@'
1931
+ * @param {*} p Function parameter
1932
+ * @param {object} options
1933
+ * @param {boolean} options.implicitAliases Whether parameter aliases are used implicitly
1934
+ * @returns {string} Parameter name
1935
+ */
1936
+ function functionParamName(p, { implicitAliases }) {
1937
+ if (implicitAliases && csdl.$Version !== '2.0' && SYSTEM_QUERY_OPTIONS.includes(p.$Name.toLowerCase()))
1938
+ return `@${p.$Name}`;
1939
+ return p.$Name;
1940
+ }
1941
+
1942
+ /**
1943
+ * Populate a structured (JSON-encoded) function parameter
1944
+ * @param {Parameter} param Parameter Object to augment
1945
+ * @param {*} p Function parameter
1946
+ * @param {object} options
1947
+ * @param {boolean} options.implicitAliases Whether parameter aliases are used implicitly
1948
+ * @param {Array} options.pathSegments Path segments to augment for inline parameters
1949
+ */
1950
+ function addStructuredFunctionParam(param, p, { implicitAliases, pathSegments }) {
1951
+ param.in = 'query';
1952
+ if (implicitAliases) {
1953
+ param.name = functionParamName(p, { implicitAliases });
1954
+ } else {
1955
+ pathSegments.push(`${p.$Name}=@${p.$Name}`);
1956
+ param.name = `@${p.$Name}`;
1957
+ }
1958
+ param.schema = { type: 'string' };
1959
+ param.description = param.description ? `${param.description} \n` : '';
1960
+ param.description += `This is ${
1961
+ p.$Collection ? 'a ' : ''
1962
+ }URL-encoded JSON ${
1963
+ p.$Collection ? 'array with items ' : ''
1964
+ }of type ${
1965
+ meta.namespaceQualifiedName(p.$Type ?? 'Edm.String')
1966
+ }, see [Complex and Collection Literals](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_ComplexandCollectionLiterals)`;
1967
+ param.example = p.$Collection ? '[]' : '{}';
1968
+ }
1969
+
1970
+ /**
1971
+ * Populate a simple (primitive) function parameter
1972
+ * @param {Parameter} param Parameter Object to augment
1973
+ * @param {*} p Function parameter
1974
+ * @param {*} type Resolved model element of the parameter type
1975
+ * @param {object} options
1976
+ * @param {boolean} options.implicitAliases Whether parameter aliases are used implicitly
1977
+ * @param {Array} options.pathSegments Path segments to augment for inline parameters
1978
+ */
1979
+ function addSimpleFunctionParam(param, p, type, { implicitAliases, pathSegments }) {
1980
+ if (implicitAliases) {
1981
+ param.in = 'query';
1982
+ } else {
1983
+ pathSegments.push(`${p.$Name}={${p.$Name}}`);
1984
+ param.in = 'path';
1985
+ }
1986
+ param.name = functionParamName(p, { implicitAliases });
1987
+ if (!p.$Type || p.$Type === "Edm.String" || (type && (!type.$Type || type.$Type === "Edm.String"))) {
1988
+ param.description = param.description ? `${param.description} \n` : '';
1989
+ param.description += "String value needs to be enclosed in single quotes";
1990
+ }
1991
+ param.schema = getSchema(p, '', true, true);
1825
1992
  }
1826
1993
 
1827
1994
  /**
@@ -1902,7 +2069,15 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1902
2069
  description
1903
2070
  }
1904
2071
  };
1905
- const CountPropertyObj = { [csdl.$Version > '4.0' ? '@count' : '@odata.count']: ref('count') };
2072
+ const countProperty = { [csdl.$Version > '4.0' ? '@count' : '@odata.count']: ref('count') };
2073
+ const nextLinkKey = csdl.$Version > '4.0' ? '@nextLink' : '@odata.nextLink';
2074
+ const nextLinkProperty = {
2075
+ [nextLinkKey]: {
2076
+ type: 'string',
2077
+ format: 'uri',
2078
+ description: 'URL of the next page in server-driven paging, see [Server-driven Paging](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)'
2079
+ }
2080
+ };
1906
2081
  if (code != 204) {
1907
2082
  const s = getSchema(type);
1908
2083
  r[code].content = {
@@ -1915,8 +2090,9 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
1915
2090
  type: 'object',
1916
2091
  title: `Collection of ${nameParts(type.$Type ? type.$Type : 'Edm.String').name}`,
1917
2092
  properties: {
1918
- ...(isCount && CountPropertyObj),
1919
- value: s
2093
+ ...(isCount && countProperty),
2094
+ value: s,
2095
+ ...nextLinkProperty
1920
2096
  }
1921
2097
  };
1922
2098
  }
@@ -2126,47 +2302,13 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2126
2302
  const isKey = keyMap(type);
2127
2303
  const required = Object.keys(isKey);
2128
2304
  const schemaProperties = {};
2129
- let isCount = true;
2130
- if (csdl[qualifier]?.$Annotations) {
2131
- const annotations = csdl[qualifier].$Annotations[`${qualifier}.EntityContainer/${name}`];
2132
- if (annotations && annotations[meta.voc.Capabilities.CountRestrictions] && annotations[meta.voc.Capabilities.CountRestrictions]?.Countable === false) {
2133
- isCount = false;
2134
- }
2135
- }
2305
+ const isCount = isCountable(qualifier, name);
2136
2306
  const properties = propertiesOfStructuredType(type);
2137
2307
  const expandRestrictions = type[meta.voc.Capabilities.ExpandRestrictions] ?? {};
2138
2308
  const nonExpandableProperties = expandRestrictions.NonExpandableProperties ?? [];
2139
2309
  Object.keys(properties).forEach(iName => {
2140
- if (nonExpandableProperties.includes(iName)) {
2141
- return;
2142
- }
2143
- const property = properties[iName];
2144
- if (suffix === SUFFIX.read) schemaProperties[iName] = getSchema(property);
2145
- if ((Object.prototype.hasOwnProperty.call(property, '@Common.FieldControl')) && property['@Common.FieldControl'] === 'Mandatory') { required.push(iName) }
2146
- if (property.$Kind == 'NavigationProperty') {
2147
- if (property.$Collection && suffix === "" && isCount === true) {
2148
- schemaProperties[`${iName}@${csdl.$Version === '4.0' ? 'odata.' : ''}count`] = ref('count');
2149
- }
2150
- if (property[meta.voc.Core.Permissions] != "Read" && !property[meta.voc.Core.Computed] && (property.$ContainsTarget || property.$OnDelete === 'Cascade')) {
2151
- if (suffix === SUFFIX.create) {
2152
- schemaProperties[iName] = getSchema(property, SUFFIX.create);
2153
- }
2154
- if (suffix === SUFFIX.update && !property[meta.voc.Core.Immutable]) {
2155
- schemaProperties[iName] = getSchema(property, SUFFIX.create);
2156
- }
2157
- }
2158
- } else {
2159
- if (property[meta.voc.Core.Permissions] === "Read" || property[meta.voc.Core.Computed] || property[meta.voc.Core.ComputedDefaultValue]) {
2160
- const index = required.indexOf(iName);
2161
- if (index != -1) required.splice(index, 1);
2162
- }
2163
- if (!(property[meta.voc.Core.Permissions] === "Read" || property[meta.voc.Core.Computed])) {
2164
- if (suffix === SUFFIX.create)
2165
- schemaProperties[iName] = getSchema(property, SUFFIX.create);
2166
- if (suffix === SUFFIX.update && !isKey[iName] && !property[meta.voc.Core.Immutable])
2167
- schemaProperties[iName] = getSchema(property, SUFFIX.update);
2168
- }
2169
- }
2310
+ if (nonExpandableProperties.includes(iName)) return;
2311
+ addStructuredTypeProperty(iName, properties[iName], { suffix, isCount, isKey, required, schemaProperties });
2170
2312
  });
2171
2313
 
2172
2314
 
@@ -2189,13 +2331,90 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2189
2331
  schemas[schemaName].description = description;
2190
2332
  }
2191
2333
 
2192
- if (meta.derivedTypes[baseName]) {
2193
- schemas[schemaName].anyOf = [];
2194
- meta.derivedTypes[baseName].forEach((derivedType) => {
2195
- schemas[schemaName].anyOf.push(ref(derivedType, suffix));
2196
- });
2197
- if (!type.$Abstract) schemas[schemaName].anyOf.push({});
2334
+ addDerivedTypesAnyOf(schemas[schemaName], baseName, type, suffix);
2335
+ }
2336
+
2337
+ /**
2338
+ * Determine whether count is enabled for an entity set via CountRestrictions
2339
+ * @param {string} qualifier Qualifier for structured type
2340
+ * @param {string} name Simple name of structured type
2341
+ * @return {boolean} Whether count is enabled
2342
+ */
2343
+ function isCountable(qualifier, name) {
2344
+ const annotations = csdl[qualifier]?.$Annotations?.[`${qualifier}.EntityContainer/${name}`];
2345
+ return annotations?.[meta.voc.Capabilities.CountRestrictions]?.Countable !== false;
2346
+ }
2347
+
2348
+ /**
2349
+ * Append anyOf entries for derived types to a schema
2350
+ * @param {*} schema Schema Object to augment
2351
+ * @param {string} baseName Qualified base type name
2352
+ * @param {*} type Structured type
2353
+ * @param {string} suffix Suffix for read/create/update
2354
+ */
2355
+ function addDerivedTypesAnyOf(schema, baseName, type, suffix) {
2356
+ if (!meta.derivedTypes[baseName]) return;
2357
+ schema.anyOf = meta.derivedTypes[baseName].map((derivedType) => ref(derivedType, suffix));
2358
+ if (!type.$Abstract) schema.anyOf.push({});
2359
+ }
2360
+
2361
+ /**
2362
+ * Add a single property of a structured type to the schema being built
2363
+ * @param {string} iName Property name
2364
+ * @param {*} property Property definition
2365
+ * @param {object} options
2366
+ * @param {string} options.suffix Suffix for read/create/update
2367
+ * @param {boolean} options.isCount Whether count is enabled
2368
+ * @param {*} options.isKey Map of key properties
2369
+ * @param {string[]} options.required Accumulator of required property names
2370
+ * @param {*} options.schemaProperties Accumulator of schema properties
2371
+ */
2372
+ function addStructuredTypeProperty(iName, property, { suffix, isCount, isKey, required, schemaProperties }) {
2373
+ if (isMandatoryField(property)) required.push(iName);
2374
+
2375
+ if (property.$Kind == 'NavigationProperty') {
2376
+ addNavigationProperty(iName, property, { suffix, isCount, schemaProperties });
2377
+ } else {
2378
+ addScalarProperty(iName, property, { suffix, isKey, required, schemaProperties });
2379
+ }
2380
+ }
2381
+
2382
+ /**
2383
+ * Add a navigation property to the schema being built
2384
+ * @param {string} iName Property name
2385
+ * @param {*} property Navigation property definition
2386
+ * @param {object} options
2387
+ * @param {string} options.suffix Suffix for read/create/update
2388
+ * @param {boolean} options.isCount Whether count is enabled
2389
+ * @param {*} options.schemaProperties Accumulator of schema properties
2390
+ */
2391
+ function addNavigationProperty(iName, property, { suffix, isCount, schemaProperties }) {
2392
+ if (isNavBackReference(property)) return;
2393
+
2394
+ if (suffix === SUFFIX.read) schemaProperties[iName] = getSchema(property);
2395
+ if (property.$Collection && suffix === SUFFIX.read && isCount) schemaProperties[`${iName}@${csdl.$Version === '4.0' ? 'odata.' : ''}count`] = ref('count');
2396
+ if (isNavWritable(property) && suffix === SUFFIX.create) schemaProperties[iName] = getSchema(property, SUFFIX.create);
2397
+ if (isNavWritable(property) && suffix === SUFFIX.update && !property[meta.voc.Core.Immutable]) schemaProperties[iName] = getSchema(property, SUFFIX.create);
2398
+ }
2399
+
2400
+ /**
2401
+ * Add a scalar (non-navigation) property to the schema being built
2402
+ * @param {string} iName Property name
2403
+ * @param {*} property Property definition
2404
+ * @param {object} options
2405
+ * @param {string} options.suffix Suffix for read/create/update
2406
+ * @param {*} options.isKey Map of key properties
2407
+ * @param {string[]} options.required Accumulator of required property names
2408
+ * @param {*} options.schemaProperties Accumulator of schema properties
2409
+ */
2410
+ function addScalarProperty(iName, property, { suffix, isKey, required, schemaProperties }) {
2411
+ if (suffix === SUFFIX.read) schemaProperties[iName] = getSchema(property);
2412
+ if (isScalarReadOnly(property)) {
2413
+ const idx = required.indexOf(iName);
2414
+ if (idx !== -1) required.splice(idx, 1);
2198
2415
  }
2416
+ if (isScalarWritable(property) && suffix === SUFFIX.create) schemaProperties[iName] = getSchema(property, SUFFIX.create);
2417
+ if (isScalarWritable(property) && suffix === SUFFIX.update && !isKey[iName] && !property[meta.voc.Core.Immutable]) schemaProperties[iName] = getSchema(property, SUFFIX.update);
2199
2418
  }
2200
2419
 
2201
2420
  /**
@@ -2349,255 +2568,214 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2349
2568
  }
2350
2569
 
2351
2570
  /**
2352
- * Construct Schema Object for model object referencing a type
2571
+ * Construct the base Schema Object for the referenced type, before applying
2572
+ * facets like nullability, defaults, validation, collection wrapping, and
2573
+ * descriptions.
2353
2574
  * @param {*} element referencing a type
2354
- * @return {*} Schema Object
2575
+ * @param {string} suffix Optional suffix for referenced structured-type schemas
2576
+ * @return {Schema} Schema Object
2355
2577
  */
2356
- function getSchema(element, suffix = '', forParameter = false, forFunction = false) {
2578
+ function getBaseSchema(element, suffix) {
2579
+ const constant = CONSTANT_EDM_SCHEMAS[element.$Type];
2580
+ if (constant) return structuredClone(constant);
2357
2581
 
2358
- /** @type {Schema} */
2359
- let s = {};
2360
2582
  switch (element.$Type) {
2361
- case 'Edm.AnnotationPath':
2362
- case 'Edm.meta.modelElementPath':
2363
- case 'Edm.NavigationPropertyPath':
2364
- case 'Edm.PropertyPath':
2365
- s = { type: 'string' };
2366
- break;
2367
- case 'Edm.Binary':
2368
- s = {
2583
+ case 'Edm.Binary': {
2584
+ const s = /** @type {import('./types.d.ts').StringSchema} */({
2369
2585
  type: 'string',
2370
2586
  format: 'base64url'
2371
- };
2587
+ });
2372
2588
  if (element.$MaxLength) s.maxLength = Math.ceil(4 * element.$MaxLength / 3);
2373
- break;
2374
- case 'Edm.Boolean':
2375
- s = { type: 'boolean' };
2376
- break;
2377
- case 'Edm.Byte':
2378
- s = {
2379
- type: 'integer',
2380
- format: 'uint8'
2381
- };
2382
- break;
2383
- case 'Edm.Date':
2384
- s = {
2385
- type: 'string',
2386
- format: 'date',
2387
- example: '2017-04-13'
2388
- };
2389
- break;
2589
+ return s;
2590
+ }
2390
2591
  case 'Edm.DateTime':
2391
2592
  case 'Edm.DateTimeOffset':
2392
- s = {
2393
- type: 'string',
2394
- format: 'date-time',
2395
- example: `2017-04-13T15:51:04${isNaN(element.$Precision) || element.$Precision === 0 ? '' : `.${'0'.repeat(element.$Precision)}`}Z`
2396
- };
2397
- break;
2398
- case 'Edm.Decimal': {
2399
- const preDecimal = /** @type {const}*/({ type: 'number', format: 'decimal' })
2400
- s = {
2401
- anyOf: [preDecimal, { type: 'string' }],
2402
- example: 0
2403
- };
2404
- if (!isNaN(element.$Precision)) s['x-sap-precision'] = element.$Precision;
2405
- if (!isNaN(element.$Scale)) s['x-sap-scale'] = element.$Scale;
2406
- const scale = !isNaN(element.$Scale) ? element.$Scale : null;
2407
- if (scale !== null) {
2408
- // Node.js 20 has problems with negative exponents, 10 ** -5 --> 0.000009999999999999999
2409
- if (scale <= 0)
2410
- preDecimal.multipleOf = 10 ** -scale;
2411
- else
2412
- preDecimal.multipleOf = 1 / 10 ** scale;
2413
- }
2414
- if (element.$Precision < 16) {
2415
- const limit = 10 ** (element.$Precision - scale);
2416
- const delta = 10 ** -scale;
2417
- preDecimal.maximum = limit - delta;
2418
- preDecimal.minimum = -preDecimal.maximum;
2419
- }
2420
- break;
2421
- }
2422
- case 'Edm.Double':
2423
- s = {
2424
- anyOf: [{ type: 'number', format: 'double' }, { type: 'string' }],
2425
- example: 3.14
2426
- };
2427
- break;
2428
- case 'Edm.Duration':
2429
- s = {
2430
- type: 'string',
2431
- format: 'duration',
2432
- example: 'P4DT15H51M04S'
2433
- };
2434
- break;
2593
+ return dateTimeSchema(element);
2594
+ case 'Edm.Decimal':
2595
+ return decimalSchema(element);
2435
2596
  case 'Edm.GeographyPoint':
2436
- case 'Edm.GeometryPoint':
2437
- s = ref('geoPoint');
2597
+ case 'Edm.GeometryPoint': {
2598
+ const s = ref('geoPoint');
2438
2599
  typesToInline.geoPoint = true;
2439
- break;
2440
- case 'Edm.Guid':
2441
- s = {
2442
- type: 'string',
2443
- format: 'uuid',
2444
- example: '01234567-89ab-cdef-0123-456789abcdef'
2445
- };
2446
- break;
2447
- case 'Edm.Int16':
2448
- s = {
2449
- type: 'integer',
2450
- format: 'int16'
2451
- };
2452
- break;
2453
- case 'Edm.Int32':
2454
- s = {
2455
- type: 'integer',
2456
- format: 'int32'
2457
- };
2458
- break;
2459
- case 'Edm.Int64':
2460
- s = {
2461
- anyOf: [{ type: 'integer', format: 'int64' }, { type: 'string' }],
2462
- example: "42"
2463
- };
2464
- break;
2465
- case 'Edm.PrimitiveType':
2466
- s = {
2467
- anyOf: [{ type: 'boolean' }, { type: 'number' }, { type: 'string' }]
2468
- };
2469
- break;
2470
- case 'Edm.SByte':
2471
- s = {
2472
- type: 'integer',
2473
- format: 'int8'
2474
- };
2475
- break;
2476
- case 'Edm.Single':
2477
- s = {
2478
- anyOf: [{ type: 'number', format: 'float' }, { type: 'string' }],
2479
- example: 3.14
2480
- };
2481
- break;
2600
+ return s;
2601
+ }
2482
2602
  case 'Edm.Stream':
2483
- // eslint-disable-next-line no-case-declarations
2484
- const jsonSchema = element[meta.voc.JSON.Schema];
2485
- if (jsonSchema) {
2486
- if (typeof jsonSchema == 'string')
2487
- s = JSON.parse(jsonSchema);
2488
- else
2489
- s = jsonSchema;
2490
- } else {
2491
- s = {
2492
- type: 'string',
2493
- format: 'base64url'
2494
- };
2495
- }
2496
- break;
2603
+ return streamSchema(element);
2497
2604
  case 'Edm.String':
2498
- case undefined: {
2499
- s = { type: 'string' };
2500
- if (element.$MaxLength) s.maxLength = element.$MaxLength;
2501
- const pattern = element[meta.voc.Validation.Pattern];
2502
- if (pattern) s.pattern = pattern;
2503
- break;
2504
- }
2505
- case 'Edm.TimeOfDay':
2506
- s = {
2507
- type: 'string',
2508
- format: 'time',
2509
- example: '15:51:04'
2510
- };
2511
- break;
2605
+ case undefined:
2606
+ return stringSchema(element);
2512
2607
  default:
2513
2608
  if (element.$Type.startsWith('Edm.')) {
2514
2609
  DEBUG?.(`Unknown type: ${element.$Type}`);
2515
- } else {
2516
- const type = meta.modelElement(element.$Type);
2517
- const isStructured = type && ['ComplexType', 'EntityType'].includes(type.$Kind);
2518
- s = ref(element.$Type, (isStructured ? suffix : ''));
2519
- if (element.$MaxLength) {
2520
- s = {
2521
- allOf: [s],
2522
- maxLength: element.$MaxLength
2523
- };
2524
- }
2610
+ return {};
2525
2611
  }
2612
+ return referencedTypeSchema(element, suffix);
2526
2613
  }
2614
+ }
2527
2615
 
2528
- allowedValues(s, element);
2616
+ /**
2617
+ * Construct the base Schema Object for Edm.DateTime(Offset), rendering the
2618
+ * fractional-seconds part of the example according to the Precision facet.
2619
+ * @param {*} element referencing an Edm.DateTime(Offset) type
2620
+ * @return {Schema} Schema Object
2621
+ */
2622
+ function dateTimeSchema(element) {
2623
+ return {
2624
+ type: /** @type {const} */('string'),
2625
+ format: 'date-time',
2626
+ example: `2017-04-13T15:51:04${isNaN(element.$Precision) || element.$Precision === 0 ? '' : `.${'0'.repeat(element.$Precision)}`}Z`
2627
+ };
2628
+ }
2529
2629
 
2530
- if (element.$Nullable) {
2531
- if (s.$ref) s = { allOf: [s] };
2532
- s.nullable = true;
2630
+ /**
2631
+ * Construct the base Schema Object for Edm.String (and untyped elements),
2632
+ * honouring MaxLength and Validation.Pattern facets.
2633
+ * @param {*} element referencing an Edm.String or untyped element
2634
+ * @return {Schema} Schema Object
2635
+ */
2636
+ function stringSchema(element) {
2637
+ const s = /** @type {import('./types.d.ts').StringSchema} */({ type: 'string' });
2638
+ if (element.$MaxLength) s.maxLength = element.$MaxLength;
2639
+ const pattern = element[meta.voc.Validation.Pattern];
2640
+ if (pattern) s.pattern = pattern;
2641
+ return s;
2642
+ }
2643
+
2644
+ /**
2645
+ * Construct the base Schema Object for Edm.Stream, honouring an inline
2646
+ * JSON.Schema annotation (parsed if provided as a string) and falling back
2647
+ * to a base64url-encoded string.
2648
+ * @param {*} element referencing an Edm.Stream type
2649
+ * @return {Schema} Schema Object
2650
+ */
2651
+ function streamSchema(element) {
2652
+ const jsonSchema = element[meta.voc.JSON.Schema];
2653
+ if (jsonSchema) {
2654
+ if (typeof jsonSchema == 'string')
2655
+ return JSON.parse(jsonSchema);
2656
+ return jsonSchema;
2533
2657
  }
2658
+ return {
2659
+ type: 'string',
2660
+ format: 'base64url'
2661
+ };
2662
+ }
2534
2663
 
2535
- if (element.$DefaultValue !== undefined) {
2536
- if (s.$ref) s = { allOf: [s] };
2537
- s.default = element.$DefaultValue;
2664
+ /**
2665
+ * Construct the base Schema Object for a reference to a named (non-Edm)
2666
+ * type, wrapping in an allOf with maxLength when the element carries one.
2667
+ * @param {*} element referencing a named type
2668
+ * @param {string} suffix Optional suffix for structured-type schemas
2669
+ * @return {Schema} Schema Object
2670
+ */
2671
+ function referencedTypeSchema(element, suffix) {
2672
+ const type = meta.modelElement(element.$Type);
2673
+ const isStructured = type && ['ComplexType', 'EntityType'].includes(type.$Kind);
2674
+ let s = ref(element.$Type, (isStructured ? suffix : ''));
2675
+ if (element.$MaxLength) {
2676
+ s = {
2677
+ allOf: [s],
2678
+ maxLength: element.$MaxLength
2679
+ };
2538
2680
  }
2681
+ return s;
2682
+ }
2539
2683
 
2540
- if (element[meta.voc.Core.Example]) {
2541
- if (s.$ref) s = { allOf: [s] };
2542
- s.example = element[meta.voc.Core.Example].Value;
2684
+ /**
2685
+ * Construct the base Schema Object for Edm.Decimal, honouring Precision and
2686
+ * Scale facets (multipleOf, minimum/maximum, x-sap-precision/scale).
2687
+ * @param {*} element referencing an Edm.Decimal type
2688
+ * @return {Schema} Schema Object
2689
+ */
2690
+ function decimalSchema(element) {
2691
+ const preDecimal = /** @type {const}*/({ type: 'number', format: 'decimal' })
2692
+ const s = {
2693
+ anyOf: [preDecimal, { type: 'string' }],
2694
+ example: 0
2695
+ };
2696
+ if (!isNaN(element.$Precision)) s['x-sap-precision'] = element.$Precision;
2697
+ if (!isNaN(element.$Scale)) s['x-sap-scale'] = element.$Scale;
2698
+ const scale = !isNaN(element.$Scale) ? element.$Scale : null;
2699
+ if (scale !== null) {
2700
+ // Node.js 20 has problems with negative exponents, 10 ** -5 --> 0.000009999999999999999
2701
+ if (scale <= 0)
2702
+ preDecimal.multipleOf = 10 ** -scale;
2703
+ else
2704
+ preDecimal.multipleOf = 1 / 10 ** scale;
2543
2705
  }
2706
+ if (element.$Precision < 16) {
2707
+ const limit = 10 ** (element.$Precision - scale);
2708
+ const delta = 10 ** -scale;
2709
+ preDecimal.maximum = limit - delta;
2710
+ preDecimal.minimum = -preDecimal.maximum;
2711
+ }
2712
+ return s;
2713
+ }
2544
2714
 
2545
- /** @returns {s is import('./types.d.ts').StringSchema} */
2546
- const isStringSchema = s => s?.type === 'string'
2547
- /** @returns {s is import('./types.d.ts').NumberSchema} */
2548
- const isNumberSchema = s => s?.type === 'number' || s?.type === 'integer'
2549
- /** @returns {s is import('./types.d.ts').AnyOf} */
2550
- const isAnyOfSchema = s => Boolean(s?.anyOf)
2715
+ /**
2716
+ * Construct Schema Object for model object referencing a type
2717
+ * @param {*} element referencing a type
2718
+ * @return {*} Schema Object
2719
+ */
2720
+ function getSchema(element, suffix = '', forParameter = false, forFunction = false) {
2551
2721
 
2552
- if (forFunction) {
2553
- if (s.example && typeof s.example === "string") {
2554
- s.example = `${pathValuePrefix(element.$Type)}${s.example
2555
- }${pathValueSuffix(element.$Type)} `;
2556
- }
2557
- if (isStringSchema(s)) {
2558
- if (s.pattern) {
2559
- const pre = pathValuePrefix(element.$Type);
2560
- const suf = pathValueSuffix(element.$Type);
2561
- s.pattern = s.pattern.replace(/^\^/, `^ ${pre} (`);
2562
- s.pattern = s.pattern.replace(/\$$/, `)${suf} $`);
2563
- } else if (!element.$Type || element.$Type === "Edm.String") {
2564
- s.pattern = "^'([^']|'')*'$";
2565
- }
2566
- }
2567
- if (element.$Nullable) {
2568
- s.default = "null";
2569
- if (isStringSchema(s) && s.pattern) {
2570
- s.pattern = s.pattern
2571
- .replace(/^\^/, "^(null|")
2572
- .replace(/\$$/, ")$");
2573
- }
2574
- }
2575
- }
2722
+ /** @type {Schema} */
2723
+ let s = getBaseSchema(element, suffix);
2576
2724
 
2577
- if (element[meta.voc.Validation.Maximum] !== undefined) {
2578
- if (s.$ref) s = { allOf: [s] };
2579
- if (isAnyOfSchema(s) && isNumberSchema(s.anyOf[0])) {
2580
- s.anyOf[0].maximum = element[meta.voc.Validation.Maximum];
2581
- } else if (isNumberSchema(s)) {
2582
- s.maximum = element[meta.voc.Validation.Maximum];
2583
- }
2584
- // TODO: this implies that we could be handling an AnyOfSchema here. So exclusiveMinimum is attach to that? Or to its first element, as above?
2585
- // @ts-expect-error
2586
- if (element[meta.voc.Validation.Maximum + meta.voc.Validation.Exclusive]) s.exclusiveMaximum = true;
2587
- }
2725
+ allowedValues(s, element);
2588
2726
 
2589
- if (element[meta.voc.Validation.Minimum] !== undefined) {
2590
- if (s.$ref) s = { allOf: [s] };
2591
- if (isAnyOfSchema(s) && isNumberSchema(s.anyOf[0])) {
2592
- s.anyOf[0].minimum = element[meta.voc.Validation.Minimum];
2593
- } else if (isNumberSchema(s)) {
2594
- s.minimum = element[meta.voc.Validation.Minimum];
2595
- }
2596
- // TODO: see above
2597
- // @ts-expect-error
2598
- if (element[meta.voc.Validation.Minimum + meta.voc.Validation.Exclusive]) s.exclusiveMinimum = true;
2727
+ s = applyValueFacets(s, element);
2728
+
2729
+ if (forFunction) applyFunctionFacets(s, element);
2730
+
2731
+ s = applyRangeValidation(s, element, 'Maximum');
2732
+ s = applyRangeValidation(s, element, 'Minimum');
2733
+
2734
+ s = applyContainerFacets(s, element, forParameter);
2735
+
2736
+ return s;
2737
+ }
2738
+
2739
+ /**
2740
+ * Wrap a $ref schema in an allOf so that sibling keywords can be attached
2741
+ * without violating the OpenAPI rule that $ref siblings are ignored.
2742
+ * @param {Schema} s Schema Object
2743
+ * @return {Schema} The original schema, or an allOf wrapper around a $ref
2744
+ */
2745
+ function wrapRefForKeywords(s) {
2746
+ return s.$ref ? { allOf: [s] } : s;
2747
+ }
2748
+
2749
+ /**
2750
+ * Apply nullability, default value, and Core.Example facets in place.
2751
+ * @param {Schema} s Schema Object
2752
+ * @param {*} element Model element referencing a type
2753
+ * @return {Schema} The (possibly rewrapped) Schema Object
2754
+ */
2755
+ function applyValueFacets(s, element) {
2756
+ if (element.$Nullable) {
2757
+ s = wrapRefForKeywords(s);
2758
+ s.nullable = true;
2759
+ }
2760
+ if (element.$DefaultValue !== undefined) {
2761
+ s = wrapRefForKeywords(s);
2762
+ s.default = element.$DefaultValue;
2763
+ }
2764
+ if (element[meta.voc.Core.Example]) {
2765
+ s = wrapRefForKeywords(s);
2766
+ s.example = element[meta.voc.Core.Example].Value;
2599
2767
  }
2768
+ return s;
2769
+ }
2600
2770
 
2771
+ /**
2772
+ * Apply collection wrapping, description, and ODM/ER annotation facets.
2773
+ * @param {Schema} s Schema Object
2774
+ * @param {*} element Model element referencing a type
2775
+ * @param {boolean} forParameter Suppress description when used as a parameter
2776
+ * @return {Schema} The (possibly rewrapped) Schema Object
2777
+ */
2778
+ function applyContainerFacets(s, element, forParameter) {
2601
2779
  if (element.$Collection) {
2602
2780
  s = {
2603
2781
  type: 'array',
@@ -2611,7 +2789,7 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2611
2789
 
2612
2790
  const description = forParameter ? undefined : (element[meta.voc.Core.LongDescription] || element[meta.voc.Core.Description]);
2613
2791
  if (description) {
2614
- if (s.$ref) s = { allOf: [s] };
2792
+ s = wrapRefForKeywords(s);
2615
2793
  s.description = description;
2616
2794
  }
2617
2795
 
@@ -2627,6 +2805,67 @@ see [Expand](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-prot
2627
2805
  return s;
2628
2806
  }
2629
2807
 
2808
+ /** @returns {s is import('./types.d.ts').StringSchema} */
2809
+ function isStringSchema(s) { return s?.type === 'string'; }
2810
+ /** @returns {s is import('./types.d.ts').NumberSchema} */
2811
+ function isNumberSchema(s) { return s?.type === 'number' || s?.type === 'integer'; }
2812
+ /** @returns {s is import('./types.d.ts').AnyOf} */
2813
+ function isAnyOfSchema(s) { return Boolean(s?.anyOf); }
2814
+
2815
+ /**
2816
+ * Apply function-import formatting to a Schema Object in place: wrap the
2817
+ * example and pattern with the OData key-value delimiters and encode
2818
+ * nullability for function parameters passed in the request path.
2819
+ * @param {Schema} s Schema Object to augment in place
2820
+ * @param {*} element Model element referencing a type
2821
+ */
2822
+ function applyFunctionFacets(s, element) {
2823
+ if (s.example && typeof s.example === "string") {
2824
+ s.example = `${pathValuePrefix(element.$Type)}${s.example
2825
+ }${pathValueSuffix(element.$Type)} `;
2826
+ }
2827
+ if (isStringSchema(s)) {
2828
+ if (s.pattern) {
2829
+ const pre = pathValuePrefix(element.$Type);
2830
+ const suf = pathValueSuffix(element.$Type);
2831
+ s.pattern = s.pattern.replace(/^\^/, `^ ${pre} (`);
2832
+ s.pattern = s.pattern.replace(/\$$/, `)${suf} $`);
2833
+ } else if (!element.$Type || element.$Type === "Edm.String") {
2834
+ s.pattern = "^'([^']|'')*'$";
2835
+ }
2836
+ }
2837
+ if (element.$Nullable) {
2838
+ s.default = "null";
2839
+ if (isStringSchema(s) && s.pattern) {
2840
+ s.pattern = s.pattern
2841
+ .replace(/^\^/, "^(null|")
2842
+ .replace(/\$$/, ")$");
2843
+ }
2844
+ }
2845
+ }
2846
+
2847
+ /**
2848
+ * Apply a Validation.Maximum or Validation.Minimum facet to a Schema Object.
2849
+ * Rewraps a $ref schema in an allOf so the numeric bound can be attached,
2850
+ * and honours the matching Exclusive flag.
2851
+ * @param {Schema} s Schema Object
2852
+ * @param {*} element Model element referencing a type
2853
+ * @param {'Maximum'|'Minimum'} kind Which bound to apply
2854
+ * @return {Schema} The (possibly rewrapped) Schema Object
2855
+ */
2856
+ function applyRangeValidation(s, element, kind) {
2857
+ if (element[meta.voc.Validation[kind]] === undefined) return s;
2858
+ if (s.$ref) s = { allOf: [s] };
2859
+ const bound = kind.toLowerCase();
2860
+ if (isAnyOfSchema(s) && isNumberSchema(s.anyOf[0])) {
2861
+ s.anyOf[0][bound] = element[meta.voc.Validation[kind]];
2862
+ } else if (isNumberSchema(s)) {
2863
+ s[bound] = element[meta.voc.Validation[kind]];
2864
+ }
2865
+ if (element[meta.voc.Validation[kind] + meta.voc.Validation.Exclusive]) s[`exclusive${kind}`] = true;
2866
+ return s;
2867
+ }
2868
+
2630
2869
  /**
2631
2870
  * Add allowed values enum to Schema Object for string-like model element
2632
2871
  * @param {*} schema Schema Object to augment