Compare commits

..

52 Commits

Author SHA1 Message Date
sjvans
9536a7f34c rm server.js (#327) 2022-03-04 12:57:35 +01:00
sjvans
079620463f use dummy-auth 2022-02-24 09:10:01 +01:00
sjvans
d53d4de105 SAP Community Call 2022-02-24 08:30:26 +01:00
sjvans
b13ed5cc8d graphql 2021-11-04 17:31:57 +01:00
Daniel
eaaf0d29a5 Updated package-lock.json 2021-11-04 10:37:33 +01:00
Daniel
64fe700d1e ... 2021-11-04 10:37:33 +01:00
Daniel
5c3cec973e Using bookstore as composite app 2021-11-04 10:37:33 +01:00
Daniel
680a6ae68f Introduced bookstore composite app 2021-11-04 10:37:33 +01:00
Daniel
366b0f8f9a Using flat fiori app folder 2021-11-04 10:37:33 +01:00
Daniel
b95df77b9a Fixed access to cds.entities 2021-11-04 10:37:33 +01:00
Christian Georgi
7f6b87171a Merge pull request #284 from SAP-samples/registry
NPM registry: more robust,  work on Windows
2021-10-26 22:21:32 +02:00
Christian Georgi
21e74bbbfb Add test for NPM registry 2021-10-26 22:17:25 +02:00
Christian Georgi
102b15c3cd NPM registry: more robust, work on Windows
- Run `npm rm` in correct dir
- Encode args in `npm conf rm` command for Powershell
- Don't cleanup in exit handler, this might not complete.
  Instead, do it on startup.
- Different cleanup command for Windows and Linux
- Explicitly close server, instead of relying on process.exit()
- Make scope configurable
2021-10-26 19:11:08 +02:00
Dr. David A. Kunz
73db2e96bc Merge pull request #283 from SAP-samples/ql-changes-typo-fix
fix typo in ql changes
2021-10-26 11:57:44 +02:00
Dr. David A. Kunz
7bb58ee2d5 Merge branch 'main' into ql-changes-typo-fix 2021-10-26 11:56:15 +02:00
D065023
27e82d16e0 fix typo 2021-10-26 11:55:33 +02:00
Dr. David A. Kunz
ff9bbe6d8d Merge pull request #282 from SAP-samples/ql-changes
Changes in ql for cds version 5.6.0
2021-10-26 11:32:09 +02:00
Dr. David A. Kunz
5f1b7b8cbf Merge branch 'main' into ql-changes 2021-10-26 11:27:27 +02:00
D065023
0253300557 Changes in ql for cds version 5.6.0 2021-10-26 11:22:43 +02:00
Daniel
139d957495 Added reviewed.count to messsages 2021-10-18 18:04:33 +02:00
Daniel
404427237b Updated reviews samples for messaging GA 2021-10-18 18:04:33 +02:00
Christian Georgi
5f89334403 Remove refs to 'master' branch 2021-10-12 18:46:21 +02:00
Christian Georgi
e612fa97ea Merge pull request #277 from SAP-samples/updated-package.json
Updated package.json
2021-10-08 11:16:10 +02:00
Christian Georgi
da2ea39466 Do not fail on absent cds-swagger-ui-express 2021-10-08 10:23:12 +02:00
Daniel
117000df71 Revert "temporarily using sqlite3 until next release to fix vulnerabilities"
This reverts commit f3ffb69d3a.
2021-10-08 07:50:04 +02:00
Daniel
f3ffb69d3a temporarily using sqlite3 until next release to fix vulnerabilities 2021-10-08 07:41:18 +02:00
Daniel
f908484973 Updated package.json 2021-10-08 06:42:50 +02:00
Christian Georgi
c4529f3cd7 Increase test timeout
At least on slower machines or when file system caches are not filled,
the default 5000 ms are not enough for the tests to finish.
2021-09-29 13:51:49 +02:00
Christian Georgi
0220400484 Avoid mixed spaces/tabs 2021-09-20 15:56:53 +02:00
dependabot[bot]
c1911b6e96 Bump axios from 0.21.1 to 0.21.4
Bumps [axios](https://github.com/axios/axios) from 0.21.1 to 0.21.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.21.1...v0.21.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-10 15:42:25 +02:00
Daniel
19083d156e Rename amount -> quantity 2021-09-10 15:39:30 +02:00
Christian Georgi
48d547e6cd Make jest really silent 2021-09-10 15:35:36 +02:00
Daniel
bae491a832 one more more more 2021-08-31 20:36:36 +02:00
Daniel
ca41a2141c one more 2021-08-31 19:30:09 +02:00
Daniel Hutzel
08f409af73 more (#267) 2021-08-31 18:05:22 +02:00
Daniel Hutzel
efa60550fb fix cds.ql (#266) 2021-08-31 13:29:05 +02:00
Daniel Hutzel
f599206bf4 Fixed cds.ql in latest release (#232)
* Fixed cds.ql in latest release

* Requires @sap/cds ^5.1.5

* fixed fixes

* More cdr tests

Co-authored-by: Christian Georgi <chgeo@users.noreply.github.com>
2021-08-31 09:59:06 +02:00
Daniel
2f5d159428 using cds.test 2021-08-30 16:08:25 +02:00
Daniel
2be3d50389 More cds.ql cleanup 2021-08-30 11:09:42 +02:00
Daniel
46b58f1b5c skipping ts test 2021-08-27 14:19:17 +02:00
Daniel
e87527cbcd fixed package-lock 2021-08-27 14:19:17 +02:00
Daniel
091844219b Upgrade to jest 27 2021-08-27 14:19:17 +02:00
Daniel
de796e5a89 Fixed '*' in upcomming release 2021-08-27 10:46:53 +02:00
Daniel
f988088412 '*' is still different 2021-08-26 06:50:13 +02:00
Daniel
c4a51ab719 fixed test 2021-08-26 06:50:13 +02:00
Daniel
f58376607a Prep for cleaning up cds.ql 2021-08-26 06:50:13 +02:00
Dr. David A. Kunz
839048d87c Merge pull request #260 from SAP-samples/fixing-test
Cascade delete test: Yes it should have been deleted
2021-08-19 12:57:56 +02:00
D065023
3b3463f889 skipped 2021-08-19 12:55:48 +02:00
D065023
d3396304ec yes it should be deleted 2021-08-19 12:45:03 +02:00
Pierre Fritsch
ae09caf7ad Enable cds watch hello
by moving the `hello` implementation into the subfolder `srv`
2021-08-03 16:01:10 +02:00
Daniel Hutzel
e1052c209b Removing workaround for glitch in drafts (#254)
* Removing workaround for glitch in drafts

* cosmetics
2021-08-02 17:20:46 +02:00
Christian Georgi
cd3aad59e1 Fix UI warnings
These were caused by the UI check not being aware of the parallel
`common.cds` file.
2021-07-14 10:11:21 +02:00
66 changed files with 796 additions and 32472 deletions

View File

@@ -5,9 +5,9 @@ name: CI
on: on:
push: push:
branches: [ master ] branches: [ main ]
pull_request: pull_request:
branches: [ master ] branches: [ main ]
jobs: jobs:
build: build:

View File

@@ -1,17 +1,22 @@
const { exec } = require ('child_process') const { exec } = require ('child_process')
const isWin = process.platform === 'win32'
const express = require ('express') const express = require ('express')
const fs = require ('fs') const fs = require ('fs')
const app = express() const app = express()
const { PORT=4444 } = process.env const { PORT=4444 } = process.env
const [,,port=PORT] = process.argv const [,,port=PORT,scope='@capire'] = process.argv
const cwd = __dirname const cwd = __dirname
// clean up on start (exit handler might not complete on Windows)
exec(isWin ? 'del *.tgz' : 'rm *.tgz', {cwd})
app.use('/-/:tarball', (req,res,next) => { app.use('/-/:tarball', (req,res,next) => {
console.debug ('GET', req.params) console.debug ('GET', req.params)
try { try {
const { tarball } = req.params const { tarball } = req.params
const [, pkg ] = /^capire-(\w+)/.exec(tarball) const [, pkg ] = /^\w+-(\w+)/.exec(tarball)
fs.lstat(tarball,(err => { fs.lstat(tarball,(err => {
if (err) exec(`npm pack ../${pkg}`,{cwd},next) if (err) exec(`npm pack ../${pkg}`,{cwd},next)
else next() else next()
@@ -25,12 +30,14 @@ app.use('/-/:tarball', (req,res,next) => {
app.use('/-', express.static(__dirname)) app.use('/-', express.static(__dirname))
app.get('/*', (req,res)=>{ app.get('/*', (req,res)=>{
const urlRegex = /^\/(@\w+)\/(\w+)/
const url = decodeURIComponent(req.url) const url = decodeURIComponent(req.url)
console.debug ('GET',url) console.debug ('GET',url)
try { try {
const [, capire, pkg ] = /^\/(@capire)\/(\w+)/.exec(url) if (!urlRegex.test(url)) return res.sendStatus(404)
const package = require (`${capire}/${pkg}/package.json`) const [, scpe, pkg ] = urlRegex.exec(url)
const tarball = `capire-${pkg}-${package.version}.tgz` const package = require (`${scpe}/${pkg}/package.json`)
const tarball = `${scpe.slice(1)}-${pkg}-${package.version}.tgz`
// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md // https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
res.json({ res.json({
"name": package.name, "name": package.name,
@@ -42,29 +49,30 @@ app.get('/*', (req,res)=>{
"name": package.name, "name": package.name,
"version": package.version, "version": package.version,
"dist": { "dist": {
"tarball": `http://localhost:${port}/-/${tarball}` "tarball": `/-/${tarball}`
}, },
} }
}, },
}) })
} catch (e) { } catch (e) {
console.error(e) if (e.code === 'MODULE_NOT_FOUND') return res.sendStatus(404)
res.sendStatus(404) console.error(e); throw e
} }
}) })
app.listen(port, ()=>{ const server = app.listen(port, ()=>{
console.log (`npm set @capire:registry=http://localhost:${port}`) const url = `http://localhost:${server.address().port}`
console.log (`@capire registry listening on http://localhost:${port}`) console.log (`npm set ${scope}:registry=${url}`)
exec(`npm set @capire:registry=http://localhost:${port}`) exec(`npm set ${scope}:registry=${url}`)
console.log (`${scope} registry listening on ${url}`)
}) })
const _exit = ()=>{ const _exit = ()=>{
console.log ('\nnpm conf rm @capire:registry') server.close()
exec('npm conf rm @capire:registry') exec(`npm conf rm "${scope}:registry"`, ()=> { process.exit() })
exec('rm *.tgz')
process.exit()
} }
process.on ('SIGTERM',_exit) process.on ('SIGTERM',_exit)
process.on ('SIGHUP',_exit) process.on ('SIGHUP',_exit)
process.on ('SIGINT',_exit) process.on ('SIGINT',_exit)

View File

@@ -105,5 +105,5 @@
"description": "### Summary\n\nThat's it! You have seen: \n- How to integrate database-specific functions in a CDS model.\n- How to switch between the two implementations for SQLite and SAP HANA." "description": "### Summary\n\nThat's it! You have seen: \n- How to integrate database-specific functions in a CDS model.\n- How to switch between the two implementations for SQLite and SAP HANA."
} }
], ],
"ref": "master" "ref": "main"
} }

View File

@@ -17,7 +17,7 @@ Find here a collection of samples for the [SAP Cloud Application Programming Mod
### Download ### Download
If you've [Git](https://git-scm.com/downloads) installed, clone this repo as shown below, otherwise [download as ZIP file](archive/master.zip). If you've [Git](https://git-scm.com/downloads) installed, clone this repo as shown below, otherwise [download as ZIP file](archive/main.zip).
```sh ```sh
git clone https://github.com/sap-samples/cloud-cap-samples samples git clone https://github.com/sap-samples/cloud-cap-samples samples

View File

@@ -10,7 +10,7 @@ const books = new Vue ({
data: { data: {
list: [], list: [],
book: undefined, book: undefined,
order: { amount:1, succeeded:'', failed:'' } order: { quantity:1, succeeded:'', failed:'' }
}, },
methods: { methods: {
@@ -26,18 +26,18 @@ const books = new Vue ({
const book = books.book = books.list [eve.currentTarget.rowIndex-1] const book = books.book = books.list [eve.currentTarget.rowIndex-1]
const res = await GET(`/Books/${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 = { amount:1 } books.order = { quantity:1 }
setTimeout (()=> $('form > input').focus(), 111) setTimeout (()=> $('form > input').focus(), 111)
}, },
async submitOrder () { async submitOrder () {
const {book,order} = books, amount = parseInt (order.amount) || 1 // REVISIT: Okra should be less strict const {book,order} = books, quantity = parseInt (order.quantity) || 1 // REVISIT: Okra should be less strict
try { try {
const res = await POST(`/submitOrder`, { amount, book: book.ID }) const res = await POST(`/submitOrder`, { quantity, book: book.ID })
book.stock = res.data.stock book.stock = res.data.stock
books.order = { amount, succeeded: `Successfully ordered ${amount} item(s).` } books.order = { quantity, succeeded: `Successfully ordered ${quantity} item(s).` }
} catch (e) { } catch (e) {
books.order = { amount, failed: e.response.data.error.message } books.order = { quantity, failed: e.response.data.error.message }
} }
} }

View File

@@ -34,7 +34,7 @@
<td>{{ book.author }}</td> <td>{{ book.author }}</td>
<td>{{ book.genre.name }}</td> <td>{{ book.genre.name }}</td>
<td class="rating-stars"> <td class="rating-stars">
{{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} {{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} ({{ book.numberOfReviews }})
</td> </td>
<td>{{ book.currency && book.currency.symbol }} {{ book.price }}</td> <td>{{ book.currency && book.currency.symbol }} {{ book.price }}</td>
</tr> </tr>
@@ -48,7 +48,7 @@
&nbsp;&nbsp; {{ book.stock }} in stock &nbsp;&nbsp; {{ book.stock }} in stock
</label> </label>
<form @submit.prevent="submitOrder" style="float:right; display:flex; flex-direction:row-reverse"> <form @submit.prevent="submitOrder" style="float:right; display:flex; flex-direction:row-reverse">
<input type="number" v-model="order.amount" v-bind:class="{ failed: order.failed }" style="width:5em"> <input type="number" v-model="order.quantity" v-bind:class="{ failed: order.failed }" style="width:5em">
<input type="submit" value="Order:" class="muted-button"> <input type="submit" value="Order:" class="muted-button">
</form> </form>
<h4> {{ book.title }} </h4> <h4> {{ book.title }} </h4>

View File

@@ -1 +1,2 @@
exports.CatalogService = require('./srv/cat-service') const { CatalogService } = require('./srv/cat-service')
module.exports = { CatalogService }

View File

@@ -11,6 +11,6 @@ service CatalogService @(path:'/browse') {
} excluding { createdBy, modifiedBy }; } excluding { createdBy, modifiedBy };
@requires: 'authenticated-user' @requires: 'authenticated-user'
action submitOrder ( book: Books:ID, amount: Integer ) returns { stock: Integer }; action submitOrder ( book: Books:ID, quantity: Integer ) returns { stock: Integer };
event OrderedBook : { book: Books:ID; amount: Integer; buyer: String }; event OrderedBook : { book: Books:ID; quantity: Integer; buyer: String };
} }

View File

@@ -1,18 +1,19 @@
const cds = require('@sap/cds') const cds = require('@sap/cds')
const { Books } = cds.entities ('sap.capire.bookshop')
class CatalogService extends cds.ApplicationService { init(){ class CatalogService extends cds.ApplicationService { init(){
const { Books } = cds.entities ('sap.capire.bookshop')
// Reduce stock of ordered books if available stock suffices // Reduce stock of ordered books if available stock suffices
this.on ('submitOrder', async req => { this.on ('submitOrder', async req => {
const {book,amount} = req.data const {book,quantity} = req.data
let {stock} = await SELECT `stock` .from (Books,book) let {stock} = await SELECT `stock` .from (Books,book)
if (stock >= amount) { if (stock >= quantity) {
await UPDATE (Books,book) .with (`stock -=`, amount) await UPDATE (Books,book) .with (`stock -=`, quantity)
await this.emit ('OrderedBook', { book, amount, buyer:req.user.id }) await this.emit ('OrderedBook', { book, quantity, buyer:req.user.id })
return { stock } return { stock }
} }
else return req.error (409,`${amount} exceeds stock for book #${book}`) else return req.error (409,`${quantity} exceeds stock for book #${book}`)
}) })
// Add some discount for overstocked books // Add some discount for overstocked books

View File

@@ -71,7 +71,7 @@ POST {{server}}/browse/submitOrder
Content-Type: application/json Content-Type: application/json
{{me}} {{me}}
{ "book":201, "amount":5 } { "book":201, "quantity":5 }
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------

39
bookstore/package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "@capire/bookstore",
"version": "1.0.0",
"dependencies": {
"@capire/bookshop": "*",
"@capire/reviews": "*",
"@capire/orders": "*",
"@capire/common": "*",
"@sap/cds": "^5",
"express": "^4.17.1"
},
"cds": {
"requires": {
"ReviewsService": {
"kind": "odata",
"model": "@capire/reviews"
},
"OrdersService": {
"kind": "odata",
"model": "@capire/orders"
},
"messaging": {
"[development]": { "kind": "file-based-messaging" },
"[hybrid]": { "kind": "enterprise-messaging-shared" },
"[production]": { "kind": "enterprise-messaging" }
},
"db": {
"kind": "sql",
"[development]": {
"model": "db/sqlite"
},
"[production]": {
"model": "db/hana"
}
}
},
"log": { "service": true }
}
}

21
bookstore/server.js Normal file
View File

@@ -0,0 +1,21 @@
const cds = require ('@sap/cds')
// Add mashup logic
cds.once('served', require('./srv/mashup'))
// Add routes to UIs from imported packages
cds.once('bootstrap',(app)=>{
app.serve ('/bookshop') .from ('@capire/bookshop','app/vue')
app.serve ('/reviews') .from ('@capire/reviews','app/vue')
app.serve ('/orders') .from('@capire/orders','app/orders')
})
// Add Swagger UI
require('./srv/swagger-ui')
// Returning cds.server
module.exports = cds.server
// For didactic reasons in capire
const { ReviewsService, OrdersService } = cds.requires
if (!ReviewsService.credentials && !OrdersService.credentials) cds.requires.messaging = false

View File

@@ -1,6 +1,7 @@
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Mashing up imported models... // Enhancing bookshop with Reviews and Orders provided through
// respective reuse packages and services
// //
using { sap.capire.bookshop.Books } from '@capire/bookshop'; using { sap.capire.bookshop.Books } from '@capire/bookshop';
@@ -8,18 +9,22 @@ using { sap.capire.bookshop.Books } from '@capire/bookshop';
// //
// Extend Books with access to Reviews and average ratings // Extend Books with access to Reviews and average ratings
// //
using { ReviewsService.Reviews } from '@capire/reviews'; using { ReviewsService.Reviews } from '@capire/reviews';
extend Books with { extend Books with {
reviews : Composition of many Reviews on reviews.subject = $self.ID; reviews : Composition of many Reviews on reviews.subject = $self.ID;
rating : Decimal; rating : Decimal;
numberOfReviews : Integer;
} }
// //
// Extend Orders with Books as Products // Extend Orders with Books as Products
// //
using { sap.capire.orders.Orders_Items } from '@capire/orders'; using { sap.capire.orders.Orders_Items } from '@capire/orders';
extend Orders_Items with { extend Orders_Items with {
book : Association to Books on product.ID = book.ID book : Association to Books on product.ID = book.ID
} }
// Add orders fiori app (in case of embedded orders service)
using from '@capire/orders/app/fiori';

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Mashing up provided and required services... // Mashing up bookshop services with required services...
// //
module.exports = async()=>{ // called by server.js module.exports = async()=>{ // called by server.js
@@ -20,30 +20,29 @@ module.exports = async()=>{ // called by server.js
CatalogService.prepend (srv => srv.on ('READ', 'Books/reviews', (req) => { CatalogService.prepend (srv => srv.on ('READ', 'Books/reviews', (req) => {
console.debug ('> delegating request to ReviewsService') console.debug ('> delegating request to ReviewsService')
const [id] = req.params, { columns, limit } = req.query.SELECT const [id] = req.params, { columns, limit } = req.query.SELECT
return ReviewsService.tx(req).read ('Reviews',columns).limit(limit).where({subject:String(id)}) return ReviewsService.read ('Reviews',columns).limit(limit).where({subject:String(id)})
})) }))
// //
// Create an order with the OrdersService when CatalogService signals a new order // Create an order with the OrdersService when CatalogService signals a new order
// //
CatalogService.on ('OrderedBook', async (msg) => { CatalogService.on ('OrderedBook', async (msg) => {
const { book, amount, 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.tx(msg).read (Books, book, b => { b.title, b.price })
return OrdersService.tx(msg).create ('Orders').entries({ return OrdersService.tx(msg).create ('Orders').entries({
OrderNo: 'Order at '+ (new Date).toLocaleString(), OrderNo: 'Order at '+ (new Date).toLocaleString(),
Items: [{ product:{ID:`${book}`}, title, price, amount }], Items: [{ product:{ID:`${book}`}, title, price, quantity }],
buyer, createdBy: buyer buyer, createdBy: buyer
}) })
}) })
// //
// Update Books' average ratings when ReviewsService signals updatd reviews // Update Books' average ratings when ReviewsService signals updated reviews
// //
ReviewsService.on ('reviewed', (msg) => { ReviewsService.on ('reviewed', (msg) => {
console.debug ('> received:', msg.event, msg.data) console.debug ('> received:', msg.event, msg.data)
const { subject, rating } = msg.data const { subject, count, rating } = msg.data
return UPDATE(Books,subject).with({rating}) return UPDATE(Books,subject).with({ numberOfReviews:count, rating })
// ^ Note: the framework will execute this and take care for db.tx
}) })
// //
@@ -51,9 +50,9 @@ module.exports = async()=>{ // called by server.js
// //
OrdersService.on ('OrderChanged', (msg) => { OrdersService.on ('OrderChanged', (msg) => {
console.debug ('> received:', msg.event, msg.data) console.debug ('> received:', msg.event, msg.data)
const { product, deltaAmount } = msg.data const { product, deltaQuantity } = msg.data
return UPDATE (Books) .where ('ID =', product) return UPDATE (Books) .where ('ID =', product)
.and ('stock >=', deltaAmount) .and ('stock >=', deltaQuantity)
.set ('stock -=', deltaAmount) .set ('stock -=', deltaQuantity)
}) })
} }

View File

@@ -0,0 +1,10 @@
// -----------------------------------------------------------------------
// Adding Swagger UI - see https://cap.cloud.sap/docs/advanced/openapi
const cds = require ('@sap/cds')
try {
const cds_swagger = require ('cds-swagger-ui-express')
cds.once ('bootstrap', app => app.use (cds_swagger()) )
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') throw err
}

View File

@@ -2,7 +2,7 @@
@bookshop = http://localhost:4004 @bookshop = http://localhost:4004
@reviews-service = {{bookshop}}/reviews @reviews-service = {{bookshop}}/reviews
# Uncomment this when running a separate reviews service # Uncomment this when running a separate reviews service
@reviews-service = http://localhost:4005/reviews # @reviews-service = http://localhost:4005/reviews

View File

@@ -1,2 +0,0 @@
# cds.requires.messaging.kind = file-based-messaging
PORT = 4004

View File

@@ -1,4 +1,5 @@
using { AdminService, sap.capire.bookshop } from '../../db/schema'; using { AdminService } from '@capire/bookshop';
using from '../common'; // to help UI linter get the complete annotations
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
@@ -86,9 +87,8 @@ annotate AdminService.Books.texts with @(
annotate AdminService.Books.texts { annotate AdminService.Books.texts {
locale @ValueList:{entity:'Languages',type:#fixed} locale @ValueList:{entity:'Languages',type:#fixed}
} }
// In addition we need to expose Languages and Books.texts through AdminService // In addition we need to expose Languages through AdminService as a target for ValueList
using { sap } from '@sap/cds/common'; using { sap } from '@sap/cds/common';
extend service AdminService { extend service AdminService {
entity Languages as projection on sap.common.Languages; @readonly entity Languages as projection on sap.common.Languages;
entity Books.texts as projection on bookshop.Books.texts;
} }

View File

@@ -1,3 +0,0 @@
<head>
<meta http-equiv="refresh" content="0;url=bookshop/index.html">
</head>

View File

@@ -1,3 +0,0 @@
<head>
<meta http-equiv="refresh" content="0;url=reviews/index.html">
</head>

View File

@@ -6,7 +6,4 @@ using from './admin/fiori-service';
using from './browse/fiori-service'; using from './browse/fiori-service';
using from './common'; using from './common';
using from '@capire/common'; using from '@capire/bookstore/srv/mashup';
// only works in case of embedded orders service
using from '@capire/orders/app/orders/fiori-service';

View File

@@ -2,10 +2,7 @@
"name": "@capire/fiori", "name": "@capire/fiori",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@capire/bookshop": "*", "@capire/bookstore": "*",
"@capire/reviews": "*",
"@capire/orders": "*",
"@capire/common": "*",
"@sap/cds": "^5", "@sap/cds": "^5",
"express": "^4.17.1", "express": "^4.17.1",
"passport": "^0.4.1" "passport": "^0.4.1"
@@ -15,9 +12,6 @@
"watch": "cds watch" "watch": "cds watch"
}, },
"cds": { "cds": {
"hana": {
"deploy-format": "hdbtable"
},
"requires": { "requires": {
"auth": { "auth": {
"strategy": "dummy" "strategy": "dummy"
@@ -26,18 +20,17 @@
"kind": "odata", "kind": "odata",
"model": "@capire/reviews" "model": "@capire/reviews"
}, },
"--> OrdersService": { "OrdersService": {
"kind": "odata", "kind": "odata",
"model": "@capire/orders" "model": "@capire/orders"
}, },
"db": { "messaging": {
"kind": "sql", "[production]": { "kind": "enterprise-messaging" },
"[development]": { "[development]": { "kind": "file-based-messaging" },
"model": "db/sqlite" "[hybrid!]": { "kind": "enterprise-messaging-shared" }
}, },
"[production]": { "hana": {
"model": "db/hana" "deploy-format": "hdbtable"
}
} }
} }
} }

View File

@@ -1,23 +1 @@
const cds = require ('@sap/cds') module.exports = require('@capire/bookstore/server.js')
module.exports = cds.server
cds.once('bootstrap',(app)=>{
app.use ('/orders/webapp', _from('@capire/orders/app/orders/webapp/manifest.json'))
app.use ('/bookshop', _from('@capire/bookshop/app/vue/index.html'))
app.use ('/reviews', _from('@capire/reviews/app/vue/index.html'))
})
cds.once('served', require('./srv/mashup'))
// Swagger UI - see https://cap.cloud.sap/docs/advanced/openapi
if (process.env.NODE_ENV !== 'production') {
const cds_swagger = require ('cds-swagger-ui-express')
cds.once ('bootstrap', app => app.use (cds_swagger()) )
}
// -----------------------------------------------------------------------
// Helper for serving static content from npm-installed packages
const {static} = require('express')
const {dirname} = require('path')
const _from = target => static (dirname (require.resolve(target)))

1
graphql/.env Normal file
View File

@@ -0,0 +1 @@
PORT = 4007

View File

@@ -0,0 +1,4 @@
book_ID;number;title
201;1;Chapter 1
201;2;Chapter 2
201;3;Chapter 3
Internal Server Error - Bruno's Gitea
500 Internal Server Error

Gitea Version: 1.24.4