Compare commits

..

7 Commits

Author SHA1 Message Date
Christian Georgi
ae1129ebab Better email address 2025-04-02 13:02:17 +02:00
ajinkyapatil8190
815a4e9a64 Reuse Version update from dep to toml 2025-03-07 14:05:38 +01:00
Ajinkya Patil
14ac3efaa1 Update dep5 2025-02-25 20:09:17 +01:00
Ajinkya Patil
9c476eb348 Adding the reuse badge 2025-02-25 20:08:49 +01:00
Daniel Hutzel
23bea0f629 cosmetics 2025-01-31 14:42:40 +01:00
dependabot[bot]
8c6ba30673 Bump the production-dependencies group across 1 directory with 3 updates (#790)
Bumps the production-dependencies group with 3 updates in the / directory: [@sap/cds](https://cap.cloud.sap/), [express](https://github.com/expressjs/express) and [@cap-js-community/odata-v2-adapter](https://github.com/cap-js-community/odata-v2-adapter).


Updates `@sap/cds` from 8.5.0 to 8.6.1

Updates `express` from 4.21.1 to 4.21.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...4.21.2)

Updates `@cap-js-community/odata-v2-adapter` from 1.13.8 to 1.14.0
- [Release notes](https://github.com/cap-js-community/odata-v2-adapter/releases)
- [Changelog](https://github.com/cap-js-community/odata-v2-adapter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/cap-js-community/odata-v2-adapter/compare/v1.13.8...v1.14.0)

---
updated-dependencies:
- dependency-name: "@sap/cds"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@cap-js-community/odata-v2-adapter"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-27 13:27:56 +00:00
dependabot[bot]
06956b1077 Bump the development-dependencies group across 1 directory with 4 updates (#794)
Bumps the development-dependencies group with 4 updates in the / directory: [@cap-js/cds-types](https://github.com/cap-js/cds-types), [@cap-js/sqlite](https://github.com/cap-js/cds-dbs), [axios](https://github.com/axios/axios) and [eslint](https://github.com/eslint/eslint).


Updates `@cap-js/cds-types` from 0.8.0 to 0.9.0
- [Release notes](https://github.com/cap-js/cds-types/releases)
- [Changelog](https://github.com/cap-js/cds-types/blob/main/CHANGELOG.md)
- [Commits](https://github.com/cap-js/cds-types/compare/v0.8.0...v0.9.0)

Updates `@cap-js/sqlite` from 1.7.7 to 1.7.8
- [Release notes](https://github.com/cap-js/cds-dbs/releases)
- [Changelog](https://github.com/cap-js/cds-dbs/blob/main/release-please-config.json)
- [Commits](https://github.com/cap-js/cds-dbs/compare/sqlite-v1.7.7...sqlite-v1.7.8)

Updates `axios` from 1.7.8 to 1.7.9
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.8...v1.7.9)

Updates `eslint` from 9.16.0 to 9.19.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.16.0...v9.19.0)

---
updated-dependencies:
- dependency-name: "@cap-js/cds-types"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: "@cap-js/sqlite"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development-dependencies
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-27 14:26:02 +01:00
16 changed files with 172 additions and 176 deletions

View File

@@ -1,29 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: cloud-cap-samples
Upstream-Contact: <Christian Georgi (christian.georgi@sap.com)>
Source: https://github.com/SAP-samples/cloud-cap-samples
Disclaimer: The code in this project may include calls to APIs (“API Calls”) of
SAP or third-party products or services developed outside of this project
(“External Products”).
“APIs” means application programming interfaces, as well as their respective
specifications and implementing code that allows software to communicate with
other software.
API Calls to External Products are not licensed under the open source license
that governs this project. The use of such API Calls and related External
Products are subject to applicable additional agreements with the relevant
provider of the External Products. In no event shall the open source license
that governs this project grant any rights in or to any External Products,or
alter, expand or supersede any terms of the applicable additional agreements.
If you have a valid license agreement with SAP for the use of a particular SAP
External Product, then you may make use of any API Calls included in this
projects code for that SAP External Product, subject to the terms of such
license agreement. If you do not have a valid license agreement for the use of
a particular SAP External Product, then you may only make use of any API Calls
in this project for that SAP External Product for your internal, non-productive
and non-commercial test and evaluation of such API Calls. Nothing herein grants
you any rights to use or access any SAP External Product, or provide any third
parties the right to use of access any SAP External Product, through API Calls.
Files: *
Copyright: 2019-2020 SAP SE or an SAP affiliate company and cap-cloud-samples
License: Apache-2.0

View File

@@ -1,3 +1,6 @@
[![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/cloud-cap-samples)](https://api.reuse.software/info/github.com/SAP-samples/cloud-cap-samples)
# Welcome to cap/samples # Welcome to cap/samples
Find here a collection of samples for the [SAP Cloud Application Programming Model](https://cap.cloud.sap) organized in a simplistic [monorepo setup](samples.md#all-in-one-monorepo). Find here a collection of samples for the [SAP Cloud Application Programming Model](https://cap.cloud.sap) organized in a simplistic [monorepo setup](samples.md#all-in-one-monorepo).

11
REUSE.toml Normal file
View File

@@ -0,0 +1,11 @@
version = 1
SPDX-PackageName = "cloud-cap-samples"
SPDX-PackageSupplier = "<CAP (cap@sap.com)>"
SPDX-PackageDownloadLocation = "https://github.com/SAP-samples/cloud-cap-samples"
SPDX-PackageComment = "The code in this project may include calls to APIs (“API Calls”) of\n SAP or third-party products or services developed outside of this project\n (“External Products”).\n “APIs” means application programming interfaces, as well as their respective\n specifications and implementing code that allows software to communicate with\n other software.\n API Calls to External Products are not licensed under the open source license\n that governs this project. The use of such API Calls and related External\n Products are subject to applicable additional agreements with the relevant\n provider of the External Products. In no event shall the open source license\n that governs this project grant any rights in or to any External Products,or\n alter, expand or supersede any terms of the applicable additional agreements.\n If you have a valid license agreement with SAP for the use of a particular SAP\n External Product, then you may make use of any API Calls included in this\n projects code for that SAP External Product, subject to the terms of such\n license agreement. If you do not have a valid license agreement for the use of\n a particular SAP External Product, then you may only make use of any API Calls\n in this project for that SAP External Product for your internal, non-productive\n and non-commercial test and evaluation of such API Calls. Nothing herein grants\n you any rights to use or access any SAP External Product, or provide any third\n parties the right to use of access any SAP External Product, through API Calls."
[[annotations]]
path = "**.**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2019-2025 SAP SE or an SAP affiliate company and cap-cloud-samples"
SPDX-License-Identifier = "Apache-2.0"

View File

@@ -19,13 +19,13 @@ const books = Vue.createApp ({
search: ({target:{value:v}}) => books.fetch(v && '&$search='+v), search: ({target:{value:v}}) => books.fetch(v && '&$search='+v),
async fetch (etc='') { async fetch (etc='') {
const {data} = await GET(`/Books?${etc}`) const {data} = await GET(`/ListOfBooks?$expand=genre($select=name),currency($select=symbol)${etc}`)
books.list = data.value books.list = data.value
}, },
async inspect (eve) { async inspect (eve) {
const book = books.book = books.list [eve.currentTarget.rowIndex-1] const book = books.book = books.list [eve.currentTarget.rowIndex-1]
const res = await GET(`/Book/${book.ID}?$select=descr,stock,image`) const res = await GET(`/Books/${book.ID}?$select=descr,stock,image`)
Object.assign (book, res.data) Object.assign (book, res.data)
books.order = { quantity:1 } books.order = { quantity:1 }
setTimeout (()=> $('form > input').focus(), 111) setTimeout (()=> $('form > input').focus(), 111)

View File

@@ -45,11 +45,11 @@
<tr v-for="book in list" v-bind:id="book.ID" v-on:click="inspect"> <tr v-for="book in list" v-bind:id="book.ID" v-on:click="inspect">
<td>{{ book.title }}</td> <td>{{ book.title }}</td>
<td>{{ book.author }}</td> <td>{{ book.author }}</td>
<td>{{ book.genre }}</td> <td>{{ book.genre.name }}</td>
<td class="rating-stars"> <td class="rating-stars">
{{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} ({{ book.numberOfReviews }}) {{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} ({{ book.numberOfReviews }})
</td> </td>
<td>{{ book.currency }} {{ book.price }}</td> <td>{{ book.currency && book.currency.symbol }} {{ book.price }}</td>
</tr> </tr>
</table> </table>

View File

@@ -1,5 +1,5 @@
using { sap.capire.bookshop as my } from '../db/schema'; using { sap.capire.bookshop as my } from '../db/schema';
service AdminService @(requires:'admin', path:'/admin') { service AdminService @(requires:'admin', path:'/admin') {
entity Books as projection on my.Books; entity Books as projection on my.Books;
// entity Authors as projection on my.Authors; entity Authors as projection on my.Authors;
} }

View File

@@ -2,20 +2,15 @@ using { sap.capire.bookshop as my } from '../db/schema';
service CatalogService @(path:'/browse') { service CatalogService @(path:'/browse') {
/** For displaying lists of Books */ /** For displaying lists of Books */
@readonly entity Books as projection on Book excluding { descr }; @readonly entity ListOfBooks as projection on Books
excluding { descr };
/** For display in details pages */ /** For display in details pages */
@readonly entity Book as projection on my.Books { *, @readonly entity Books as projection on my.Books { *,
currency.name as currencyName, // flattened author.name as author
currency.symbol as currency, // flattened } excluding { createdBy, modifiedBy };
author.name as author, // flattened
genre.name as genre, // flattened
} excluding {
createdBy, modifiedBy, // as end users shouldn't see them
localized, texts, // as end users don't need them
};
@requires: 'authenticated-user' @requires: 'authenticated-user'
action submitOrder ( book: Book:ID, quantity: Integer ) returns { stock: Integer }; action submitOrder ( book: Books:ID, quantity: Integer ) returns { stock: Integer };
event OrderedBook : { book: Book:ID; quantity: Integer; buyer: String }; event OrderedBook : { book: Books:ID; quantity: Integer; buyer: String };
} }

View File

@@ -3,10 +3,10 @@ const cds = require('@sap/cds')
class CatalogService extends cds.ApplicationService { init() { class CatalogService extends cds.ApplicationService { init() {
const { Books } = cds.entities('sap.capire.bookshop') const { Books } = cds.entities('sap.capire.bookshop')
const { Books:Book } = this.entities const { ListOfBooks } = this.entities
// Add some discount for overstocked books // Add some discount for overstocked books
this.after('each', Book, book => { this.after('each', ListOfBooks, book => {
if (book.stock > 111) book.title += ` -- 11% discount!` if (book.stock > 111) book.title += ` -- 11% discount!`
}) })

View File

@@ -1,6 +1,5 @@
@server = http://localhost:4004 @server = http://localhost:4004
@me = Authorization: Basic {{$processEnv USER}}: @me = Authorization: Basic {{$processEnv USER}}:
@alice = Authorization: Basic alice:
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
@@ -17,11 +16,11 @@ GET {{server}}/browse/$metadata
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Browse Books as any user # Browse Books as any user
GET {{server}}/admin/Books? GET {{server}}/browse/ListOfBooks?
# &$select=title,stock # &$select=title,stock
&$expand=genre &$expand=genre
# &sap-language=de # &sap-language=de
{{alice}} {{me}}
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
@@ -31,13 +30,13 @@ GET {{server}}/admin/Authors?
# &$expand=books($select=title;$expand=currency) # &$expand=books($select=title;$expand=currency)
# &$filter=ID eq 101 # &$filter=ID eq 101
# &sap-language=de # &sap-language=de
{{alice}} Authorization: Basic alice:
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Create Author # Create Author
POST {{server}}/admin/Authors POST {{server}}/admin/Authors
Content-Type: application/json;IEEE754Compatible=true Content-Type: application/json;IEEE754Compatible=true
{{alice}} Authorization: Basic alice:
{ {
"ID": 112, "ID": 112,
@@ -50,7 +49,7 @@ Content-Type: application/json;IEEE754Compatible=true
# Create book # Create book
POST {{server}}/admin/Books POST {{server}}/admin/Books
Content-Type: application/json;IEEE754Compatible=true Content-Type: application/json;IEEE754Compatible=true
{{alice}} Authorization: Basic alice:
{ {
"ID": 2, "ID": 2,
@@ -68,7 +67,7 @@ Content-Type: application/json;IEEE754Compatible=true
# Put image to books # Put image to books
PUT {{server}}/admin/Books(2)/image PUT {{server}}/admin/Books(2)/image
Content-Type: image/png Content-Type: image/png
{{alice}} Authorization: Basic alice:
data:image/png;base64,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 data:image/png;base64,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

View File

@@ -28,8 +28,8 @@ module.exports = async()=>{ // called by server.js
// //
CatalogService.on ('OrderedBook', async (msg) => { CatalogService.on ('OrderedBook', async (msg) => {
const { book, quantity, buyer } = msg.data const { book, quantity, buyer } = msg.data
const { title, price } = await db.tx(msg).read (Books, book, b => { b.title, b.price }) const { title, price } = await db.read (Books, book, b => { b.title, b.price })
return OrdersService.tx(msg).create ('Orders').entries({ return OrdersService.create ('Orders').entries({
OrderNo: 'Order at '+ (new Date).toLocaleString(), OrderNo: 'Order at '+ (new Date).toLocaleString(),
Items: [{ product:{ID:`${book}`}, title, price, quantity }], Items: [{ product:{ID:`${book}`}, title, price, quantity }],
buyer, createdBy: buyer buyer, createdBy: buyer

View File

@@ -4,7 +4,7 @@ using CatalogService from '@capire/bookstore';
// //
// Books Object Page // Books Object Page
// //
annotate CatalogService.Book with @(UI : { annotate CatalogService.Books with @(UI : {
HeaderInfo : { HeaderInfo : {
TypeName : '{i18n>Book}', TypeName : '{i18n>Book}',
TypeNamePlural : '{i18n>Books}', TypeNamePlural : '{i18n>Books}',
@@ -24,7 +24,7 @@ annotate CatalogService.Book with @(UI : {
FieldGroup #Price : {Data : [ FieldGroup #Price : {Data : [
{Value : price}, {Value : price},
{ {
Value : currencyName, Value : currency.symbol,
Label : '{i18n>Currency}' Label : '{i18n>Currency}'
}, },
]}, ]},
@@ -35,11 +35,11 @@ annotate CatalogService.Book with @(UI : {
// //
// Books List Page // Books List Page
// //
annotate CatalogService.Book with @(UI : { annotate CatalogService.Books with @(UI : {
SelectionFields : [ SelectionFields : [
ID, ID,
price, price,
currencyName currency_code
], ],
LineItem : [ LineItem : [
{ {
@@ -50,10 +50,8 @@ annotate CatalogService.Book with @(UI : {
Value : author, Value : author,
Label : '{i18n>Author}' Label : '{i18n>Author}'
}, },
{Value : genre}, {Value : genre.name},
{Value : price}, {Value : price},
{Value : currencyName}, {Value : currency.symbol},
] ]
}) { }, );
currencyName @Common.Label : '{i18n>Currency}';
};

View File

@@ -18,6 +18,7 @@ annotate my.Books with @(
ID, ID,
author_ID, author_ID,
price, price,
currency_code
], ],
LineItem : [ LineItem : [
{ Value: ID, Label: '{i18n>Title}' }, { Value: ID, Label: '{i18n>Title}' },
@@ -25,6 +26,7 @@ annotate my.Books with @(
{ Value: genre.name }, { Value: genre.name },
{ Value: stock }, { Value: stock },
{ Value: price }, { Value: price },
{ Value: currency.symbol },
] ]
} }
) { ) {
@@ -61,7 +63,7 @@ annotate my.Books with {
title @title: '{i18n>Title}'; title @title: '{i18n>Title}';
genre @title: '{i18n>Genre}' @Common: { Text: genre.name, TextArrangement: #TextOnly }; genre @title: '{i18n>Genre}' @Common: { Text: genre.name, TextArrangement: #TextOnly };
author @title: '{i18n>Author}' @Common: { Text: author.name, TextArrangement: #TextOnly }; author @title: '{i18n>Author}' @Common: { Text: author.name, TextArrangement: #TextOnly };
price @title: '{i18n>Price}' @Measures.ISOCurrency : currency; price @title: '{i18n>Price}' @Measures.ISOCurrency : currency_code;
stock @title: '{i18n>Stock}'; stock @title: '{i18n>Stock}';
descr @title: '{i18n>Description}' @UI.MultiLineText; descr @title: '{i18n>Description}' @UI.MultiLineText;
image @title: '{i18n>Image}'; image @title: '{i18n>Image}';

111
package-lock.json generated
View File

@@ -108,14 +108,14 @@
} }
}, },
"node_modules/@cap-js-community/odata-v2-adapter": { "node_modules/@cap-js-community/odata-v2-adapter": {
"version": "1.13.8", "version": "1.14.0",
"resolved": "https://registry.npmjs.org/@cap-js-community/odata-v2-adapter/-/odata-v2-adapter-1.13.8.tgz", "resolved": "https://registry.npmjs.org/@cap-js-community/odata-v2-adapter/-/odata-v2-adapter-1.14.0.tgz",
"integrity": "sha512-IYkUUJLMS8sNL+6H8NOT17pMKweItjEUqV9EctuHw8+pWsFLcK3GehztZrtPS9DfEBOD9tC/aPNU5+b5unmZrQ==", "integrity": "sha512-L4yIHml7Pc3dpSiCCJkOADje7kXgMvAIhFx6ZdeWwBnniPiul++8zCbRMIIjjwFKuujTwjoprb7C4IzZdYlAfQ==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"body-parser": "^1.20.3", "body-parser": "^1.20.3",
"body-parser-xml": "^2.0.5", "body-parser-xml": "^2.0.5",
"express": "^4.21.1", "express": "^4.21.2",
"express-fileupload": "^1.5.1", "express-fileupload": "^1.5.1",
"http-proxy-middleware": "^3.0.3", "http-proxy-middleware": "^3.0.3",
"xml2js": "^0.6.2" "xml2js": "^0.6.2"
@@ -125,17 +125,15 @@
} }
}, },
"node_modules/@cap-js/cds-types": { "node_modules/@cap-js/cds-types": {
"version": "0.8.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/@cap-js/cds-types/-/cds-types-0.8.0.tgz", "resolved": "https://registry.npmjs.org/@cap-js/cds-types/-/cds-types-0.9.0.tgz",
"integrity": "sha512-iy+Rc4C6tnFuBwTIREcrFBVp0vKVN+iB5WoZFcBX7b5y7rUvK9Pz/5YHplacyQpwzxUc8Iv+CXG6LeWH/b7Qqw==", "integrity": "sha512-AD4WGAOOSszaleQQqheIo0hHm50zk3NejMlHsuG6cLh4EyK/kozvcx8hkWfAkUT/s11fa8OjyMhztFCy8b5DAA==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "SEE LICENSE IN LICENSE", "license": "SEE LICENSE IN LICENSE",
"dependencies": {
"@types/express": "^4.17.21"
},
"peerDependencies": { "peerDependencies": {
"@sap/cds": "^8.0.0" "@sap/cds": "^8.0.0",
"@types/express": ">=4"
} }
}, },
"node_modules/@cap-js/db-service": { "node_modules/@cap-js/db-service": {
@@ -152,9 +150,9 @@
} }
}, },
"node_modules/@cap-js/sqlite": { "node_modules/@cap-js/sqlite": {
"version": "1.7.7", "version": "1.7.8",
"resolved": "https://registry.npmjs.org/@cap-js/sqlite/-/sqlite-1.7.7.tgz", "resolved": "https://registry.npmjs.org/@cap-js/sqlite/-/sqlite-1.7.8.tgz",
"integrity": "sha512-SOmFJMr6pjWOniFRkJsrI0BpQEQT5Q8o+IVZ/LXFj6+bAe0NQQztzxhMQx62V/Px3u58JJM3xkPMU+QC5PcJHw==", "integrity": "sha512-llFn0LGNIdlsfU4KjzyuIMvlQhKxXodq4GIt9yStmmX/av/twwHR8SyUmTJirRH4IkNtpCsuNYpsI+bYO2Xklg==",
"dev": true, "dev": true,
"license": "SEE LICENSE", "license": "SEE LICENSE",
"dependencies": { "dependencies": {
@@ -259,11 +257,14 @@
} }
}, },
"node_modules/@eslint/core": { "node_modules/@eslint/core": {
"version": "0.9.0", "version": "0.10.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
"integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
},
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
} }
@@ -293,9 +294,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "9.16.0", "version": "9.19.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
"integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -313,12 +314,13 @@
} }
}, },
"node_modules/@eslint/plugin-kit": { "node_modules/@eslint/plugin-kit": {
"version": "0.2.3", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
"integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/core": "^0.10.0",
"levn": "^0.4.1" "levn": "^0.4.1"
}, },
"engines": { "engines": {
@@ -389,9 +391,9 @@
} }
}, },
"node_modules/@sap/cds": { "node_modules/@sap/cds": {
"version": "8.5.0", "version": "8.6.1",
"resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.5.0.tgz", "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-8.6.1.tgz",
"integrity": "sha512-mRiLBPcY5vC1xi21pPqzMtp1HY9FOOFajkiuSArqnwtiyp2fxqWVombuVE9lTB2UyBl9bL8XXwrpjzDftIbnBg==", "integrity": "sha512-JYHRrGs6Tgle5Vmj/o3BaQkOBVcroweOrXhhiUVH6twISy+Yi2cWZdTr0EFFEt94FI1dVqvrVnEM67jEjOQImQ==",
"license": "SEE LICENSE IN LICENSE", "license": "SEE LICENSE IN LICENSE",
"dependencies": { "dependencies": {
"@sap/cds-compiler": ">=5.1", "@sap/cds-compiler": ">=5.1",
@@ -464,6 +466,7 @@
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/connect": "*", "@types/connect": "*",
"@types/node": "*" "@types/node": "*"
@@ -475,6 +478,7 @@
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@@ -491,6 +495,7 @@
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/body-parser": "*", "@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33", "@types/express-serve-static-core": "^4.17.33",
@@ -504,6 +509,7 @@
"integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/node": "*", "@types/node": "*",
"@types/qs": "*", "@types/qs": "*",
@@ -516,7 +522,8 @@
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/@types/http-proxy": { "node_modules/@types/http-proxy": {
"version": "1.17.15", "version": "1.17.15",
@@ -537,7 +544,8 @@
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.5.5", "version": "22.5.5",
@@ -553,14 +561,16 @@
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz",
"integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/@types/range-parser": { "node_modules/@types/range-parser": {
"version": "1.2.7", "version": "1.2.7",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"peer": true
}, },
"node_modules/@types/send": { "node_modules/@types/send": {
"version": "0.17.4", "version": "0.17.4",
@@ -568,6 +578,7 @@
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/mime": "^1", "@types/mime": "^1",
"@types/node": "*" "@types/node": "*"
@@ -579,6 +590,7 @@
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/http-errors": "*", "@types/http-errors": "*",
"@types/node": "*", "@types/node": "*",
@@ -694,9 +706,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.7.8", "version": "1.7.9",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1303,19 +1315,19 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "9.16.0", "version": "9.19.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz",
"integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.0", "@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.9.0", "@eslint/core": "^0.10.0",
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
"@eslint/js": "9.16.0", "@eslint/js": "9.19.0",
"@eslint/plugin-kit": "^0.2.3", "@eslint/plugin-kit": "^0.2.5",
"@humanfs/node": "^0.16.6", "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.1", "@humanwhocodes/retry": "^0.4.1",
@@ -1323,7 +1335,7 @@
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"ajv": "^6.12.4", "ajv": "^6.12.4",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cross-spawn": "^7.0.5", "cross-spawn": "^7.0.6",
"debug": "^4.3.2", "debug": "^4.3.2",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.2.0", "eslint-scope": "^8.2.0",
@@ -1479,9 +1491,10 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
@@ -1502,7 +1515,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@@ -1517,6 +1530,10 @@
}, },
"engines": { "engines": {
"node": ">= 0.10.0" "node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
} }
}, },
"node_modules/express-fileupload": { "node_modules/express-fileupload": {
@@ -2441,9 +2458,9 @@
} }
}, },
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/pathval": { "node_modules/pathval": {

View File

@@ -1,51 +1,51 @@
{ {
"name": "@capire/samples", "name": "@capire/samples",
"version": "2.1.0", "version": "2.1.0",
"description": "A monorepo with several samples for CAP.", "description": "A monorepo with several samples for CAP.",
"repository": "https://github.com/sap-samples/cloud-cap-samples.git", "repository": "https://github.com/sap-samples/cloud-cap-samples.git",
"author": "daniel.hutzel@sap.com", "author": "daniel.hutzel@sap.com",
"dependencies": { "dependencies": {
"@sap/cds": ">=8" "@sap/cds": ">=8"
}, },
"workspaces": [ "workspaces": [
"./bookshop", "./bookshop",
"./bookstore", "./bookstore",
"./common", "./common",
"./data-viewer", "./data-viewer",
"./fiori", "./fiori",
"./hello", "./hello",
"./media", "./media",
"./orders", "./orders",
"./loggers", "./loggers",
"./reviews" "./reviews"
], ],
"devDependencies": { "devDependencies": {
"@cap-js/cds-types": "^0", "@cap-js/cds-types": "^0",
"@cap-js/sqlite": "^1", "@cap-js/sqlite": "^1",
"axios": "^1", "axios": "^1",
"chai": "^4.3.4", "chai": "^4.3.4",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"chai-subset": "^1.6.0", "chai-subset": "^1.6.0",
"eslint": "^9", "eslint": "^9",
"semver": "^7" "semver": "^7"
}, },
"scripts": { "scripts": {
"bookshop": "cds watch bookshop", "bookshop": "cds watch bookshop",
"start": "cds watch fiori", "start": "cds watch fiori",
"fiori": "cds watch fiori", "fiori": "cds watch fiori",
"hello": "cds watch hello", "hello": "cds watch hello",
"media": "cds watch media", "media": "cds watch media",
"lint": "eslint", "lint": "eslint",
"test": "npx jest --silent", "test": "npx jest --silent",
"jest": "npx jest --silent", "jest": "npx jest --silent",
"mocha": "CDS_TEST_SILENT=y npx mocha", "mocha": "CDS_TEST_SILENT=y npx mocha",
"test:hello": "cd hello && npm test" "test:hello": "cd hello && npm test"
}, },
"mocha": { "mocha": {
"recursive": true, "recursive": true,
"parallel": true, "parallel": true,
"timeout": 6666 "timeout": 6666
}, },
"license": "SEE LICENSE IN LICENSE", "license": "SEE LICENSE IN LICENSE",
"private": true "private": true
} }

View File

@@ -27,15 +27,15 @@ describe('cap/samples - Localized Data', () => {
}) })
it('supports queries with $expand', async () => { it('supports queries with $expand', async () => {
const { data } = await GET(`/browse/Book?&$select=title,author,currencyName`, { const { data } = await GET(`/browse/Books?&$select=title,author&$expand=currency`, {
headers: { 'Accept-Language': 'de' }, headers: { 'Accept-Language': 'de' },
}) })
expect(data.value).to.containSubset([ expect(data.value).to.containSubset([
{ title: 'Sturmhöhe', author: 'Emily Brontë', currencyName: 'Pfund' }, { title: 'Sturmhöhe', author: 'Emily Brontë', currency: { name: 'Pfund' } },
{ title: 'Jane Eyre', author: 'Charlotte Brontë', currencyName: 'Pfund' }, { title: 'Jane Eyre', author: 'Charlotte Brontë', currency: { name: 'Pfund' } },
{ title: 'The Raven', author: 'Edgar Allen Poe', currencyName: 'US-Dollar' }, { title: 'The Raven', author: 'Edgar Allen Poe', currency: { name: 'US-Dollar' } },
{ title: 'Eleonora', author: 'Edgar Allen Poe', currencyName: 'US-Dollar' }, { title: 'Eleonora', author: 'Edgar Allen Poe', currency: { name: 'US-Dollar' } },
{ title: 'Catweazle', author: 'Richard Carpenter', currencyName: 'Yen' }, { title: 'Catweazle', author: 'Richard Carpenter', currency: { name: 'Yen' } },
]) ])
}) })

View File

@@ -12,20 +12,20 @@ describe('cap/samples - Bookshop APIs', () => {
'odata-version': '4.0', 'odata-version': '4.0',
}) })
expect(headers['content-type']).to.match(/application\/xml/) expect(headers['content-type']).to.match(/application\/xml/)
expect(data).to.contain('<EntitySet Name="Books" EntityType="CatalogService.Books"/>') expect(data).to.contain('<EntitySet Name="Books" EntityType="CatalogService.Books">')
expect(data).to.contain('<Annotation Term="Common.Label" String="Currency Symbol"/>') expect(data).to.contain('<Annotation Term="Common.Label" String="Currency"/>')
}) })
it('serves Books?$expand=genre,currency', async () => { it('serves ListOfBooks?$expand=genre,currency', async () => {
const Mystery = { ID: 16, name: 'Mystery', descr: null, parent_ID: 10 } const Mystery = { ID: 16, name: 'Mystery', descr: null, parent_ID: 10 }
const Romance = { ID: 15, name: 'Romance', descr: null, parent_ID: 10 } const Romance = { ID: 15, name: 'Romance', descr: null, parent_ID: 10 }
const USD = { code: 'USD', name: 'US Dollar', descr: null, symbol: '$' } const USD = { code: 'USD', name: 'US Dollar', descr: null, symbol: '$' }
const { data } = await GET `/admin/Books ${{ const { data } = await GET `/browse/ListOfBooks ${{
params: { $search: 'Po', $select: `title,author`, $expand:`genre,currency` }, params: { $search: 'Po', $select: `title,author`, $expand:`genre,currency` },
}}` }}`
expect(data.value).to.containSubset([ expect(data.value).to.containSubset([
{ ID: 251, title: 'The Raven', author_ID: 150, genre:Mystery, currency:USD }, { ID: 251, title: 'The Raven', author: 'Edgar Allen Poe', genre:Mystery, currency:USD },
{ ID: 252, title: 'Eleonora', author_ID: 150, genre:Romance, currency:USD }, { ID: 252, title: 'Eleonora', author: 'Edgar Allen Poe', genre:Romance, currency:USD },
]) ])
}) })