Compare commits

...

19 Commits

Author SHA1 Message Date
Vladislav Leonkev
13af32a865 add changes for fiori service deployment 2025-01-21 12:20:59 +01:00
Vladislav Leonkev
6dacb9cfa2 update dependencies 2025-01-17 11:12:18 +01:00
Vladislav Leonkev
78df7e05c8 keep native_hana_associations only in the root 2025-01-17 11:09:02 +01:00
Vladislav Leonkev
951daa8b43 align native_hana_associations, update dependencies, add default deployment config files 2025-01-16 11:57:43 +01:00
Vladislav Leonkev
1271c6272f add admin role 2025-01-09 15:52:37 +01:00
Vladislav Leonkev
e7e64f313d update versions 2025-01-09 15:51:53 +01:00
Vladislav Leonkev
480a16dfa2 remove bookshop service, rename app router directory 2024-12-20 16:00:36 +01:00
Vladislav Leonkev
44088c63c8 small typo 2024-12-19 09:16:51 +01:00
Vladislav Leonkev
3c5dbab4ff remove destination binding from approuter 2024-12-13 12:49:29 +01:00
Vladislav Leonkev
9cce2a45c9 bookstore: remote service credentials only for production profile 2024-12-12 16:45:54 +01:00
Vladislav Leonkev
37fb78d86e mta.yaml: optimize destinations 2024-12-12 16:04:41 +01:00
Vladislav Leonkev
6e7dc8ef6a Reviews app: provide csrfToken 2024-12-12 16:03:44 +01:00
Vladislav Leonkev
63b004ea4b add OrderChanged event definition 2024-12-12 13:57:04 +01:00
Vladislav Leonkev
1f14460797 receive OrderedBook event 2024-12-11 17:17:30 +01:00
Vladislav Leonkev
db100bfda4 bookshop: include fiori/app/services.cds 2024-12-10 11:54:57 +01:00
Vladislav Leonkev
561dc2881c sym-link vue apps in app/router 2024-12-10 11:51:51 +01:00
Vladislav Leonkev
03afb68ad9 add destinations for bookstore 2024-12-09 20:57:20 +01:00
Vladislav Leonkev
32b0e82c98 deploy orders,reviews,bookstore 2024-12-09 19:49:50 +01:00
Vladislav Leonkev
1a0df4d31d deploy bookshop 2024-12-09 15:45:34 +01:00
25 changed files with 6798 additions and 3261 deletions

1
app-router/bookshop Symbolic link
View File

@@ -0,0 +1 @@
../bookshop/app/vue

1
app-router/orders Symbolic link
View File

@@ -0,0 +1 @@
../orders/app/orders

2329
app-router/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

12
app-router/package.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "approuter",
"dependencies": {
"@sap/approuter": "^17.0.0"
},
"engines": {
"node": "^20"
},
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
}
}

1
app-router/reviews Symbolic link
View File

@@ -0,0 +1 @@
../reviews/app/vue

51
app-router/xs-app.json Normal file
View File

@@ -0,0 +1,51 @@
{
"routes": [
{
"source": "^/app/(.*)$",
"target": "$1",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate"
},
{
"source": "^/appconfig/",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate"
},
{
"source": "^/admin/(.*)$",
"target": "/admin/$1",
"destination": "bookstore-api",
"csrfProtection": true
},
{
"source": "^/browse/(.*)$",
"target": "/browse/$1",
"destination": "bookstore-api",
"csrfProtection": true
},
{
"source": "^/user/(.*)$",
"target": "/user/$1",
"destination": "bookstore-api",
"csrfProtection": true
},
{
"source": "^/odata/v4/orders/(.*)$",
"target": "/odata/v4/orders/$1",
"destination": "orders-api",
"csrfProtection": true
},
{
"source": "^/reviews/(.*)$",
"target": "/reviews/$1",
"destination": "reviews-api",
"csrfProtection": true
},
{
"source": "^(.*)$",
"target": "$1",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate"
}
]
}

View File

@@ -1,5 +1,5 @@
ID,locale,title,descr
201,de,Sturmhöhe,"Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (18181848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts."
201,fr,Les Hauts de Hurlevent,"Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme dEllis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal."
207,de,Jane Eyre,"Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte"
252,de,Eleonora,"“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit."
ID_texts,ID,locale,title,descr
0,201,de,Sturmhöhe,"Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (18181848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts."
1,201,fr,Les Hauts de Hurlevent,"Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme dEllis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal."
2,207,de,Jane Eyre,"Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte"
3,252,de,Eleonora,"“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit."
1 ID_texts ID locale title descr
2 0 201 de Sturmhöhe Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
3 1 201 fr Les Hauts de Hurlevent Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme d’Ellis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal.
4 2 207 de Jane Eyre Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
5 3 252 de Eleonora “Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.

View File

@@ -14,8 +14,19 @@
},
"dependencies": {
"@sap/cds": ">=7",
"@sap/xssec": "^4",
"@cap-js/hana": "^1",
"express": "^4.17.1"
},
"cds": {
"requires": {
"[production]": {
"auth": "xsuaa",
"db": "hana",
"messaging": "enterprise-messaging"
}
}
},
"scripts": {
"genres": "cds serve test/genres.cds",
"start": "cds-serve",

View File

@@ -7,28 +7,45 @@
"@capire/orders": "*",
"@capire/common": "*",
"@capire/data-viewer": "*",
"@sap-cloud-sdk/http-client": "^3.24.0",
"@sap-cloud-sdk/resilience": "^3.24.0",
"@sap/cds": ">=5",
"express": "^4.17.1"
"express": "^4.17.1",
"@cap-js/hana": "^1"
},
"cds": {
"requires": {
"ReviewsService": {
"kind": "odata",
"model": "@capire/reviews"
"model": "@capire/reviews",
"[production]": {
"credentials": {
"destination": "reviews-dest",
"path": "/reviews"
}
}
},
"OrdersService": {
"kind": "odata",
"model": "@capire/orders"
"model": "@capire/orders",
"[production]": {
"credentials": {
"destination": "orders-dest",
"path": "/odata/v4/orders"
}
}
},
"messaging": {
"[development]": { "kind": "file-based-messaging" },
"[hybrid]": { "kind": "enterprise-messaging-shared" },
"[production]": { "kind": "enterprise-messaging" }
},
"db": {
"kind": "sql"
"[production]": {
"auth": "xsuaa",
"db": "hana",
"messaging": "enterprise-messaging"
}
},
"log": { "service": true }
"log": {
"service": true
}
},
"scripts": {
"start": "cds-serve"
}
}
}

View File

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

139
db/src/.hdiconfig Normal file
View File

@@ -0,0 +1,139 @@
{
"file_suffixes": {
"csv": {
"plugin_name": "com.sap.hana.di.tabledata.source"
},
"hdbafllangprocedure": {
"plugin_name": "com.sap.hana.di.afllangprocedure"
},
"hdbanalyticprivilege": {
"plugin_name": "com.sap.hana.di.analyticprivilege"
},
"hdbcalculationview": {
"plugin_name": "com.sap.hana.di.calculationview"
},
"hdbcollection": {
"plugin_name": "com.sap.hana.di.collection"
},
"hdbconstraint": {
"plugin_name": "com.sap.hana.di.constraint"
},
"hdbdropcreatetable": {
"plugin_name": "com.sap.hana.di.dropcreatetable"
},
"hdbflowgraph": {
"plugin_name": "com.sap.hana.di.flowgraph"
},
"hdbfunction": {
"plugin_name": "com.sap.hana.di.function"
},
"hdbgraphworkspace": {
"plugin_name": "com.sap.hana.di.graphworkspace"
},
"hdbhadoopmrjob": {
"plugin_name": "com.sap.hana.di.virtualfunctionpackage.hadoop"
},
"hdbindex": {
"plugin_name": "com.sap.hana.di.index"
},
"hdblibrary": {
"plugin_name": "com.sap.hana.di.library"
},
"hdbmigrationtable": {
"plugin_name": "com.sap.hana.di.table.migration"
},
"hdbprocedure": {
"plugin_name": "com.sap.hana.di.procedure"
},
"hdbprojectionview": {
"plugin_name": "com.sap.hana.di.projectionview"
},
"hdbprojectionviewconfig": {
"plugin_name": "com.sap.hana.di.projectionview.config"
},
"hdbreptask": {
"plugin_name": "com.sap.hana.di.reptask"
},
"hdbresultcache": {
"plugin_name": "com.sap.hana.di.resultcache"
},
"hdbrole": {
"plugin_name": "com.sap.hana.di.role"
},
"hdbroleconfig": {
"plugin_name": "com.sap.hana.di.role.config"
},
"hdbsearchruleset": {
"plugin_name": "com.sap.hana.di.searchruleset"
},
"hdbsequence": {
"plugin_name": "com.sap.hana.di.sequence"
},
"hdbstatistics": {
"plugin_name": "com.sap.hana.di.statistics"
},
"hdbstructuredprivilege": {
"plugin_name": "com.sap.hana.di.structuredprivilege"
},
"hdbsynonym": {
"plugin_name": "com.sap.hana.di.synonym"
},
"hdbsynonymconfig": {
"plugin_name": "com.sap.hana.di.synonym.config"
},
"hdbsystemversioning": {
"plugin_name": "com.sap.hana.di.systemversioning"
},
"hdbtable": {
"plugin_name": "com.sap.hana.di.table"
},
"hdbtabledata": {
"plugin_name": "com.sap.hana.di.tabledata"
},
"hdbtabletype": {
"plugin_name": "com.sap.hana.di.tabletype"
},
"hdbtrigger": {
"plugin_name": "com.sap.hana.di.trigger"
},
"hdbview": {
"plugin_name": "com.sap.hana.di.view"
},
"hdbvirtualfunction": {
"plugin_name": "com.sap.hana.di.virtualfunction"
},
"hdbvirtualfunctionconfig": {
"plugin_name": "com.sap.hana.di.virtualfunction.config"
},
"hdbvirtualpackagehadoop": {
"plugin_name": "com.sap.hana.di.virtualpackage.hadoop"
},
"hdbvirtualpackagesparksql": {
"plugin_name": "com.sap.hana.di.virtualpackage.sparksql"
},
"hdbvirtualprocedure": {
"plugin_name": "com.sap.hana.di.virtualprocedure"
},
"hdbvirtualprocedureconfig": {
"plugin_name": "com.sap.hana.di.virtualprocedure.config"
},
"hdbvirtualtable": {
"plugin_name": "com.sap.hana.di.virtualtable"
},
"hdbvirtualtableconfig": {
"plugin_name": "com.sap.hana.di.virtualtable.config"
},
"properties": {
"plugin_name": "com.sap.hana.di.tabledata.properties"
},
"tags": {
"plugin_name": "com.sap.hana.di.tabledata.properties"
},
"txt": {
"plugin_name": "com.sap.hana.di.copyonly"
},
"hdbeshconfig": {
"plugin_name": "com.sap.hana.di.eshconfig"
}
}
}

7
db/undeploy.json Normal file
View File

@@ -0,0 +1,7 @@
[
"src/gen/**/*.hdbview",
"src/gen/**/*.hdbindex",
"src/gen/**/*.hdbconstraint",
"src/gen/**/*_drafts.hdbtable",
"src/gen/**/*.hdbcalculationview"
]

31
event-mesh.json Normal file
View File

@@ -0,0 +1,31 @@
{
"emname": "samples-multi-service-shared-db",
"version": "1.1.0",
"namespace": "cap/samples/shdb",
"options": {
"management": true,
"messagingrest": true,
"messaging": true
},
"rules": {
"topicRules": {
"publishFilter": [
"*"
],
"subscribeFilter": [
"*"
]
},
"queueRules": {
"publishFilter": [
"*"
],
"subscribeFilter": [
"*"
]
}
},
"authorities": [
"$ACCEPT_GRANTED_AUTHORITIES"
]
}

View File

@@ -2,10 +2,18 @@
"name": "@capire/fiori",
"version": "1.0.0",
"dependencies": {
"@capire/bookshop": "*",
"@capire/reviews": "*",
"@capire/orders": "*",
"@capire/common": "*",
"@capire/data-viewer": "*",
"@capire/bookstore": "*",
"@sap-cloud-sdk/http-client": "^3.24.0",
"@sap-cloud-sdk/resilience": "^3.24.0",
"@sap/cds": ">=5",
"@cap-js-community/odata-v2-adapter": "^1",
"express": "^4.17.1"
"express": "^4.17.1",
"@cap-js/hana": "^1"
},
"devDependencies": {
"@cap-js/sqlite": "^1"
@@ -18,25 +26,36 @@
"requires": {
"ReviewsService": {
"kind": "odata",
"model": "@capire/reviews"
"model": "@capire/reviews",
"[production]": {
"credentials": {
"destination": "reviews-dest",
"path": "/reviews"
}
}
},
"OrdersService": {
"kind": "odata",
"model": "@capire/orders"
},
"messaging": {
"model": "@capire/orders",
"[production]": {
"kind": "enterprise-messaging"
},
"[development]": {
"kind": "file-based-messaging"
},
"[hybrid]": {
"kind": "enterprise-messaging-shared"
"credentials": {
"destination": "orders-dest",
"path": "/odata/v4/orders"
}
}
},
"db": {
"kind": "sql"
"[production]": {
"auth": "xsuaa",
"db": "hana",
"messaging": "enterprise-messaging"
},
"[development]": {
"db": "sql",
"messaging": "file-based-messaging"
},
"[hybrid]": {
"db": "hana",
"messaging": "enterprise-messaging-shared"
},
"db-ext": {
"[development]": {

1
fiori/server.js Normal file
View File

@@ -0,0 +1 @@
require('@capire/bookstore/server')

0
fiori/srv/.gitkeep Normal file
View File

173
mta.yaml Normal file
View File

@@ -0,0 +1,173 @@
_schema-version: 3.3.0
ID: capire.samples
version: 2.1.0
description: "A monorepo with several samples for CAP."
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npm ci
- npx cds build --for hana --production --ws
- npx cds build ./orders --for nodejs --production --ws-pack
- npx cds build ./reviews --for nodejs --production --ws-pack
- npx cds build ./fiori --for nodejs --production --ws-pack
modules:
- name: orders-srv
type: nodejs
path: orders/gen/srv
parameters:
buildpack: nodejs_buildpack
readiness-health-check-type: http
readiness-health-check-http-endpoint: /health
disk-quota: 256M
memory: 256M
build-parameters:
builder: npm
provides:
- name: orders-api
properties:
srv-url: ${default-url}
requires:
- name: samples-messaging
- name: samples-db
- name: samples-auth
- name: reviews-srv
type: nodejs
path: reviews/gen/srv
parameters:
buildpack: nodejs_buildpack
readiness-health-check-type: http
readiness-health-check-http-endpoint: /health
disk-quota: 256M
memory: 256M
build-parameters:
builder: npm
provides:
- name: reviews-api
properties:
srv-url: ${default-url}
requires:
- name: samples-messaging
- name: samples-db
- name: samples-auth
- name: fiori-srv
type: nodejs
path: fiori/gen/srv
parameters:
buildpack: nodejs_buildpack
readiness-health-check-type: http
readiness-health-check-http-endpoint: /health
disk-quota: 256M
memory: 256M
build-parameters:
builder: npm
provides:
- name: bookstore-api
properties:
srv-url: ${default-url}
requires:
- name: samples-messaging
- name: samples-db
- name: samples-auth
- name: samples-destination
- name: samples-db-deployer
type: hdb
path: gen/db
parameters:
buildpack: nodejs_buildpack
requires:
- name: samples-db
- name: samples
type: approuter.nodejs
path: app-router
parameters:
keep-existing-routes: true
disk-quota: 256M
memory: 256M
requires:
- name: orders-api
group: destinations
properties:
name: orders-api # must be used in xs-app.json as well
url: ~{srv-url}
forwardAuthToken: true
- name: reviews-api
group: destinations
properties:
name: reviews-api # must be used in xs-app.json as well
url: ~{srv-url}
forwardAuthToken: true
- name: bookstore-api
group: destinations
properties:
name: bookstore-api # must be used in xs-app.json as well
url: ~{srv-url}
forwardAuthToken: true
- name: samples-auth
- name: destination-content
type: com.sap.application.content
requires:
- name: orders-api
- name: reviews-api
- name: bookstore-api
- name: samples-auth
parameters:
service-key:
name: xsuaa_service-key
- name: samples-destination
parameters:
content-target: true
build-parameters:
no-source: true
parameters:
content:
instance:
existing_destinations_policy: update
destinations:
- Name: orders-dest
URL: ~{orders-api/srv-url}
Authentication: OAuth2ClientCredentials
TokenServiceInstanceName: samples-auth
TokenServiceKeyName: xsuaa_service-key
- Name: reviews-dest
URL: ~{reviews-api/srv-url}
Authentication: OAuth2ClientCredentials
TokenServiceInstanceName: samples-auth
TokenServiceKeyName: xsuaa_service-key
resources:
- name: samples-messaging
type: org.cloudfoundry.managed-service
parameters:
service: enterprise-messaging
service-plan: default
path: ./event-mesh.json
- name: samples-db
type: com.sap.xs.hdi-container
parameters:
service: hana
service-plan: hdi-shared
- name: samples-auth
type: org.cloudfoundry.managed-service
processed-after:
- samples-messaging
parameters:
service: xsuaa
service-plan: application
path: ./xs-security.json
config:
xsappname: samples-${org}-${space}
tenant-mode: dedicated
- name: samples-destination
type: org.cloudfoundry.managed-service
parameters:
service: destination
service-plan: lite

View File

@@ -2,7 +2,21 @@
"name": "@capire/orders",
"version": "1.0.0",
"dependencies": {
"@cap-js/hana": "^1",
"@capire/common": "*",
"@sap/cds": ">=5"
"@sap/cds": ">=5",
"@sap/xssec": "^4"
},
"cds": {
"requires": {
"[production]": {
"auth": "xsuaa",
"db": "hana",
"messaging": "enterprise-messaging"
}
}
},
"scripts": {
"start": "cds-serve"
}
}
}

View File

@@ -2,4 +2,14 @@ using { sap.capire.orders as my } from '../db/schema';
service OrdersService {
entity Orders as projection on my.Orders;
@odata.draft.bypass
@(requires: 'system-user')
entity OrdersNoDraft as projection on my.Orders;
event OrderChanged {
product: String;
deltaQuantity: Integer;
}
}

6974
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -69,3 +69,25 @@ const reviews = Vue.createApp ({
// initially fill list of my reviews
reviews.fetch()
axios.interceptors.request.use(csrfToken)
function csrfToken (request) {
if (request.method === 'head' || request.method === 'get') return request
if ('csrfToken' in document) {
request.headers['x-csrf-token'] = document.csrfToken
return request
}
return fetchToken().then(token => {
document.csrfToken = token
request.headers['x-csrf-token'] = document.csrfToken
return request
}).catch(() => {
document.csrfToken = null // set mark to not try again
return request
})
function fetchToken() {
return axios.get('/', { headers: { 'x-csrf-token': 'fetch' } })
.then(res => res.headers['x-csrf-token'])
}
}

View File

@@ -1,5 +1,5 @@
subject;rating;reviewer;title;text
201;5;bob;Intriguing;Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
201;4;bob;Fascinating;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Id diam maecenas ultricies mi eget mauris pharetra et. Risus at ultrices mi tempus imperdiet nulla malesuada pellentesque. Pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci eu. Nec sagittis aliquam malesuada bibendum arcu. Eu consequat ac felis donec. Ultricies tristique nulla aliquet enim tortor at auctor urna nunc. Tortor posuere ac ut consequat semper viverra nam libero. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Scelerisque purus semper eget duis at tellus. Elementum tempus egestas sed sed risus pretium. Arcu dictum varius duis at. Amet luctus venenatis lectus magna fringilla urna. Eget velit aliquet sagittis id consectetur purus ut faucibus. Vitae auctor eu augue ut lectus. Fermentum iaculis eu non diam phasellus vestibulum.
207;2;bob;What is this?;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Libero justo laoreet sit amet cursus sit amet dictum. Nunc faucibus a pellentesque sit. Dis parturient montes nascetur ridiculus mus mauris vitae ultricies. Enim nunc faucibus a pellentesque. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Cras ornare arcu dui vivamus. Facilisi etiam dignissim diam quis enim lobortis. Et molestie ac feugiat sed. Urna neque viverra justo nec ultrices dui. Ullamcorper a lacus vestibulum sed arcu non. Volutpat ac tincidunt vitae semper quis. Dignissim sodales ut eu sem. Feugiat in fermentum posuere urna nec. At augue eget arcu dictum varius.
251;3;bob;It's dark...;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Suscipit tellus mauris a diam. Velit aliquet sagittis id consectetur purus ut. Viverra adipiscing at in tellus integer. Vitae elementum curabitur vitae nunc. Mattis ullamcorper velit sed ullamcorper morbi. Diam quis enim lobortis scelerisque. Auctor neque vitae tempus quam pellentesque nec nam aliquam. Semper auctor neque vitae tempus. Quis eleifend quam adipiscing vitae proin. Neque convallis a cras semper auctor neque vitae. Imperdiet massa tincidunt nunc pulvinar sapien et ligula. Sit amet consectetur adipiscing elit ut aliquam purus. Pretium quam vulputate dignissim suspendisse.
ID;subject;rating;reviewer;title;text
0;201;5;bob;Intriguing;Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
1;201;4;bob;Fascinating;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Id diam maecenas ultricies mi eget mauris pharetra et. Risus at ultrices mi tempus imperdiet nulla malesuada pellentesque. Pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci eu. Nec sagittis aliquam malesuada bibendum arcu. Eu consequat ac felis donec. Ultricies tristique nulla aliquet enim tortor at auctor urna nunc. Tortor posuere ac ut consequat semper viverra nam libero. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Scelerisque purus semper eget duis at tellus. Elementum tempus egestas sed sed risus pretium. Arcu dictum varius duis at. Amet luctus venenatis lectus magna fringilla urna. Eget velit aliquet sagittis id consectetur purus ut faucibus. Vitae auctor eu augue ut lectus. Fermentum iaculis eu non diam phasellus vestibulum.
2;207;2;bob;What is this?;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Libero justo laoreet sit amet cursus sit amet dictum. Nunc faucibus a pellentesque sit. Dis parturient montes nascetur ridiculus mus mauris vitae ultricies. Enim nunc faucibus a pellentesque. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Cras ornare arcu dui vivamus. Facilisi etiam dignissim diam quis enim lobortis. Et molestie ac feugiat sed. Urna neque viverra justo nec ultrices dui. Ullamcorper a lacus vestibulum sed arcu non. Volutpat ac tincidunt vitae semper quis. Dignissim sodales ut eu sem. Feugiat in fermentum posuere urna nec. At augue eget arcu dictum varius.
3;251;3;bob;It's dark...;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Suscipit tellus mauris a diam. Velit aliquet sagittis id consectetur purus ut. Viverra adipiscing at in tellus integer. Vitae elementum curabitur vitae nunc. Mattis ullamcorper velit sed ullamcorper morbi. Diam quis enim lobortis scelerisque. Auctor neque vitae tempus quam pellentesque nec nam aliquam. Semper auctor neque vitae tempus. Quis eleifend quam adipiscing vitae proin. Neque convallis a cras semper auctor neque vitae. Imperdiet massa tincidunt nunc pulvinar sapien et ligula. Sit amet consectetur adipiscing elit ut aliquam purus. Pretium quam vulputate dignissim suspendisse.
1 ID subject rating reviewer title text
2 0 201 5 bob Intriguing Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
3 1 201 4 bob Fascinating Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Id diam maecenas ultricies mi eget mauris pharetra et. Risus at ultrices mi tempus imperdiet nulla malesuada pellentesque. Pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci eu. Nec sagittis aliquam malesuada bibendum arcu. Eu consequat ac felis donec. Ultricies tristique nulla aliquet enim tortor at auctor urna nunc. Tortor posuere ac ut consequat semper viverra nam libero. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Scelerisque purus semper eget duis at tellus. Elementum tempus egestas sed sed risus pretium. Arcu dictum varius duis at. Amet luctus venenatis lectus magna fringilla urna. Eget velit aliquet sagittis id consectetur purus ut faucibus. Vitae auctor eu augue ut lectus. Fermentum iaculis eu non diam phasellus vestibulum.
4 2 207 2 bob What is this? Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Libero justo laoreet sit amet cursus sit amet dictum. Nunc faucibus a pellentesque sit. Dis parturient montes nascetur ridiculus mus mauris vitae ultricies. Enim nunc faucibus a pellentesque. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Cras ornare arcu dui vivamus. Facilisi etiam dignissim diam quis enim lobortis. Et molestie ac feugiat sed. Urna neque viverra justo nec ultrices dui. Ullamcorper a lacus vestibulum sed arcu non. Volutpat ac tincidunt vitae semper quis. Dignissim sodales ut eu sem. Feugiat in fermentum posuere urna nec. At augue eget arcu dictum varius.
5 3 251 3 bob It's dark... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Suscipit tellus mauris a diam. Velit aliquet sagittis id consectetur purus ut. Viverra adipiscing at in tellus integer. Vitae elementum curabitur vitae nunc. Mattis ullamcorper velit sed ullamcorper morbi. Diam quis enim lobortis scelerisque. Auctor neque vitae tempus quam pellentesque nec nam aliquam. Semper auctor neque vitae tempus. Quis eleifend quam adipiscing vitae proin. Neque convallis a cras semper auctor neque vitae. Imperdiet massa tincidunt nunc pulvinar sapien et ligula. Sit amet consectetur adipiscing elit ut aliquam purus. Pretium quam vulputate dignissim suspendisse.

View File

@@ -7,17 +7,21 @@
"index.cds"
],
"dependencies": {
"@cap-js/hana": "^1",
"@sap/cds": ">=5",
"@sap/xssec": "^4.2.7",
"express": "^4.17.1"
},
"cds": {
"requires": {
"messaging": {
"[development]": { "kind": "file-based-messaging" },
"[hybrid]": { "kind": "enterprise-messaging-shared" },
"[production]": { "kind": "enterprise-messaging" }
},
"db": { "kind": "sql" }
"[production]": {
"auth": "xsuaa",
"db": "hana",
"messaging": "enterprise-messaging"
}
}
},
"scripts": {
"start": "cds-serve"
}
}
}

40
xs-security.json Normal file
View File

@@ -0,0 +1,40 @@
{
"scopes": [
{
"name": "$XSAPPNAME.admin",
"description": "admin"
},
{
"name": "$XSAPPNAME.emcallback",
"description": "Enterprise-Messaging Callback Access",
"grant-as-authority-to-apps": [
"$XSSERVICENAME(samples-messaging)"
]
},
{
"name": "$XSAPPNAME.emmanagement",
"description": "Enterprise-Messaging Management Access"
}
],
"attributes": [
{
"name": "level",
"description": "level",
"valueType": "s"
}
],
"role-templates": [
{
"name": "admin",
"scope-references": [
"$XSAPPNAME.admin"
],
"description": "cap samples multi-service shared-db"
}
],
"authorities-inheritance": false,
"authorities": [
"$XSAPPNAME.emmanagement",
"$XSAPPNAME.mtcallback"
]
}