Compare commits

...

18 Commits

Author SHA1 Message Date
Daniel Hutzel
4e76d71def polishing 2025-07-24 13:52:01 +02:00
Daniel Hutzel
991e890ba9 cleanup impls 2025-07-24 13:31:45 +02:00
Daniel Hutzel
6dc1da2964 Reverting removal of cds.service.providers 2025-07-24 12:24:11 +02:00
Daniel Hutzel
65eccfad33 Moved dynamic constraints in a dedicated folder 2025-07-24 10:38:43 +02:00
Daniel Hutzel
c9021d0f46 Merge branch 'main' into dynamic-constraints 2025-07-23 17:41:16 +02:00
Daniel Hutzel
d57c29e126 constraints on service level 2025-07-23 17:36:58 +02:00
Daniel Hutzel
78cea03ae7 test with chest 2025-07-20 01:17:53 +02:00
Daniel Hutzel
ef8702acf8 more folders cleanup 2025-07-19 09:16:15 +02:00
Daniel Hutzel
044baec701 Merge branch 'main' into dynamic-constraints 2025-07-18 17:22:34 +02:00
Daniel Hutzel
dcc74fbd10 . 2025-07-18 12:53:03 +02:00
Daniel Hutzel
d1353db705 . 2025-07-17 15:51:18 +02:00
Daniel Hutzel
c10ca17546 chore: Merged fiori into bookstore and tests into subprojects 2025-07-17 13:54:32 +02:00
Daniel Hutzel
15fa7de880 . 2025-07-16 17:27:07 +02:00
Daniel Hutzel
04d659c9c2 more comments 2025-07-16 17:25:32 +02:00
Daniel Hutzel
4fc324c7fb Added instructions for ad-hoc tests in cds repl 2025-07-16 14:08:25 +02:00
Daniel Hutzel
7cd3a6d1e3 comments 2025-07-16 13:59:33 +02:00
Daniel Hutzel
b55cce3e63 case when equivalent 2025-07-16 13:49:45 +02:00
Daniel Hutzel
bd5a57189d feat: PoC for dynamic constraints using standard cds views 2025-07-16 13:23:35 +02:00
86 changed files with 1159 additions and 600 deletions

27
.vscode/launch.json vendored
View File

@@ -18,8 +18,8 @@
] ]
}, },
{ {
"name": "Fiori App", "name": "bookstore",
"command": "npx cds watch fiori", "command": "npx cds watch bookstore",
"type": "node-terminal", "type": "node-terminal",
"request": "launch", "request": "launch",
"skipFiles": [ "skipFiles": [
@@ -29,29 +29,6 @@
"**/cds/lib/req/cds-context.js", "**/cds/lib/req/cds-context.js",
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
},
{
"name": "Debug Mocha Tests",
"type": "node",
"request": "attach",
"port": 9229,
"continueOnAttach": true,
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**",
"**/cds/lib/lazy.js",
"**/cds/lib/req/cds-context.js",
"**/odata-v4/okra/**",
]
},
],
"inputs": [
{
"type": "pickString",
"id": "sample",
"description": "Which sample do you want to start?",
"options": [ "bookshop", "fiori", "reviews", "reviews" ],
"default": "bookshop"
} }
] ]
} }

View File

@@ -12,6 +12,5 @@
"**/cds/lib/req/cds-context.js", "**/cds/lib/req/cds-context.js",
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
}, }
"jest.jestCommandLine": "npx jest"
} }

View File

@@ -1,5 +1,5 @@
const cds = require('@sap/cds') const cds = require('@sap/cds')
const { GET, POST, expect } = cds.test(__dirname+'/../bookshop') const { GET, POST, expect } = cds.test(__dirname+'/..')
cds.User.default = cds.User.Privileged // hard core monkey patch cds.User.default = cds.User.Privileged // hard core monkey patch
describe('cap/samples - Custom Handlers', () => { describe('cap/samples - Custom Handlers', () => {

View File

@@ -0,0 +1,30 @@
## Experimental Dynamic Constraints
This example demonstrates how to use dynamic constraints in a CAP application. It includes a service definition and a test setup to validate the constraints.
### Prerequisites
You've setup the [_cap/samples_](https://github.com/sap-samples/cloud-cap-samples) like so:
```sh
git clone -q https://github.com/sap-samples/cloud-cap-samples cap/samples
cd cap/samples
npm install
```
### Testing
Test like that in `cds.repl` from _cap/samples_ root:
```sh
cds repl --run bookshop/test/dynamic-constraints
````
```javascript
await AdminService.create ('Books', {})
await AdminService.create ('Books', { title:' ', author_ID:150 })
await AdminService.create ('Books', { title:'x' })
await cds.validate (Books.constraints, 201)
await cds.validate (Books.constraints)
```

View File

@@ -0,0 +1,17 @@
//
// Quick and dirty implementation for cds.validate()
// using db-level constraints.
//
const cds = require('@sap/cds'); require('./validate.js')
cds.on('served', ()=> {
const { AdminService } = cds.services
AdminService.after (['CREATE','UPDATE'], (result,req) => cds.validate (req.subject, result))
})
Object.defineProperties (cds.entity.prototype, {
constraints: { get() { return cds.model.definitions[this.name+'.constraints'] }},
fields: { get() { return cds.model.definitions[this.name+'.field.control'] }},
})

View File

@@ -0,0 +1,7 @@
namespace AdminService; //> for cds.entities
using { AdminService } from '../../../srv/admin-service';
annotate AdminService with @requires: false;
extend AdminService.Authors with columns {
null as books // to simulate the exclusion of books
}

View File

@@ -0,0 +1,10 @@
namespace sap.capire.bookshop;
using from './admin-service';
view Books.field.control as select from Books { ID,
genre.name == 'Drama' ? 'readonly' :
null as price
}
extend Books with {
fc : Association to Books.field.control on fc.ID = $self.ID
}

View File

@@ -0,0 +1,76 @@
using { AdminService, sap.capire.bookshop as my } from './admin-service';
extend service AdminService with {
// entity Books.drafts as projection on AdminService.Books;
// @cds.api.ignore view Books.drafts.constraints as select from AdminService.Books.drafts mixin {
// before: Association to my.Books on before.ID = $self.ID;
// base: Association to my.Books on base.ID = $self.ID;
// } into { ID, // FIXME: compiler should resolve Books without AdminService prefix
// case
// when title is null then 'is missing'
// when trim(title)='' then 'must not be empty'
// end as title,
// ...
// }
/**
* Validation constraints for Books
*/
@cds.api.ignore view Books.constraints as select from AdminService.Books mixin {
base: Association to my.Books on base.ID = $self.ID;
} into { ID, // FIXME: compiler should resolve Books without AdminService prefix
// two-step mandatory check
case
when title is null then 'is missing'
when trim(title)='' then 'must not be empty'
end as title,
// the above is equivalent to:
// title is null ? 'is missing' : trim(title)='' ? 'must not be empty' :
// range check
stock < 0 ? 'must not be negative' :
null as stock,
// range check
price < 0 ? 'must not be negative' :
null as price,
// assert target check
genre.ID is not null and not exists genre ? 'does not exist' :
null as genre,
// multiple constraints: mandatory + assert target + special
author.ID is null ? 'is missing' : // FIXME: 1) // TODO: 2)
not exists author ? 'Author does not exist: ' || author.ID :
count(base.author.books.ID) -1 > 1 ? author.name || ' already wrote too many books' : // TODO: 3)
null as author,
} group by ID;
// 1) FIXME: expected author.ID to refer to foreign key,
// apparently that is not the case -> move one line up
// and run test to see the erroneous impact.
// 2) TODO: we should allow to write author is null instead of author.ID is null
// 3) TODO: we should support count(author.books)
/**
* Validation constraints for Authors
*/
view Authors.constraints as select from AdminService.Authors { ID, // FIXME: compiler should resolve Authors without AdminService prefix
// two-step mandatory check
name = null ? 'is missing' : trim(name)='' ? 'must not be empty' :
null as name,
// constraint related to two fields
dateOfDeath < dateOfBirth ? 'we can''t die before we are born' : null as _born_before_death,
$self._born_before_death as dateOfBirth,
$self._born_before_death as dateOfDeath,
}
}

View File

@@ -0,0 +1,34 @@
const cds = require('@sap/cds')
const $super = { validate: cds.validate, skip(){} }
/**
* Quick and dirty implementation for cds.validate() using db-level constraints.
*/
cds.validate = function (x, pk, ...columns) {
// Delegate to base impl of cds.validate() for standard input validation
if (!_is_constraints(x)) return $super.skip (...arguments)
// Support subject refs to base entities as arguments
if (x?.ref) [ x, pk ] = [ x.ref +'.constraints', pk.ID||pk ]
// Run the constraints check query
const constraints = typeof x === 'string' ? cds.model.definitions[x] || cds.error `No such constraints view: ${x}` : x
return SELECT.from (constraints, pk, columns.length && columns)
// Collect and throw errors, if any
.then (rows => (rows.map ? rows : [rows]).map (checks => {
const failed = {}; for (let c in checks) {
if (c in constraints.keys) continue
if (c[0] == '_') continue
if (checks[c]) failed[c] = checks[c]
}
if (Object.keys(failed).length) throw cds.error `Invalid input: ${failed}`
return checks
}))
}
// Helpers
const _is_constraints = x => x.ref || x.is_entity || typeof x === 'string'

View File

@@ -1,5 +1,5 @@
const cds = require('@sap/cds') const cds = require('@sap/cds')
const { expect } = cds.test.in(__dirname,'..') const { expect } = cds.test.in(__dirname,'..','..')
describe('cap/samples - Hierarchical Data', ()=>{ describe('cap/samples - Hierarchical Data', ()=>{

View File

@@ -1,4 +1,4 @@
using { sap.capire.bookshop as my } from '../db/schema'; using { sap.capire.bookshop as my } from '../../db/schema';
service TestService { service TestService {
entity Genres as projection on my.Genres; entity Genres as projection on my.Genres;
} }

View File

@@ -0,0 +1,126 @@
const cds = require('@sap/cds/lib')
const { GET, expect, axios } = cds.test(__dirname)
// Fetch API disallows GET|HEAD requests with body
if (axios.constructor.name === 'Naxios') it = it.skip
describe ('GET w/ query in body', () => {
it ('serves CQN query objects in body', async () => {
const {data:books} = await GET ('/hcql/admin', {
headers: { 'Content-Type': 'application/json' },
data: cds.ql `SELECT from Books`
})
expect(books).to.be.an('array').of.length(5)
})
it ('serves plain CQL strings in body', async () => {
const {data:books} = await GET ('/hcql/admin', {
headers: { 'Content-Type': 'text/plain' },
data: `SELECT from Books`
})
expect(books).to.be.an('array').of.length(5)
})
it ('serves complex and deep queries', async () => {
const {data:books} = await GET ('/hcql/admin', {
headers: { 'Content-Type': 'text/plain' },
data: `SELECT from Authors {
name,
books [order by title] {
title,
genre.name as genre
}
}`
})
expect(books).to.deep.equal([
{
name: "Emily Brontë",
books: [
{ title: "Wuthering Heights", genre: 'Drama' }
]
},
{
name: "Charlotte Brontë",
books: [
{ title: "Jane Eyre", genre: 'Drama' }
]
},
{
name: "Edgar Allen Poe",
books: [
{ title: "Eleonora", genre: 'Romance' },
{ title: "The Raven", genre: 'Mystery' },
]
},
{
name: "Richard Carpenter",
books: [
{ title: "Catweazle", genre: 'Fantasy' }
]
}
])
})
})
describe ('Sluggified variants', () => {
test ('GET /Books', async () => {
const {data:books} = await GET ('/hcql/admin/Books')
expect(books).to.be.an('array').of.length(5)
expect(books.length).to.eql(5) //.of.length(5)
})
test ('GET /Books/201', async () => {
const {data:book} = await GET ('/hcql/admin/Books/201')
expect(book).to.be.an('object')
expect(book).to.have.property ('title', "Wuthering Heights")
})
test ('GET /Books { title, author.name as author }' , async () => {
const {data:books} = await GET ('/hcql/admin/Books { title, author.name as author } order by ID')
expect(books).to.deep.equal ([
{ title: "Wuthering Heights", author: "Emily Brontë" },
{ title: "Jane Eyre", author: "Charlotte Brontë" },
{ title: "The Raven", author: "Edgar Allen Poe" },
{ title: "Eleonora", author: "Edgar Allen Poe" },
{ title: "Catweazle", author: "Richard Carpenter" }
])
})
test ('GET /Books/201 w/ CQL tail in URL' , async () => {
const {data:book} = await GET ('/hcql/admin/Books/201 { title, author.name as author } order by ID')
expect(book).to.deep.equal ({ title: "Wuthering Heights", author: "Emily Brontë" })
})
it ('GET /Books/201 w/ CQL fragment in body' , async () => {
const {data:book} = await GET ('/hcql/admin/Books/201', {
headers: { 'Content-Type': 'text/plain' },
data: `{ title, author.name as author }`
})
expect(book).to.deep.equal ({ title: "Wuthering Heights", author: "Emily Brontë" })
})
it ('GET /Books/201 w/ CQN fragment in body' , async () => {
const {data:book} = await GET ('/hcql/admin/Books/201', {
data: cds.ql `SELECT title, author.name as author` .SELECT
})
expect(book).to.deep.equal ({ title: "Wuthering Heights", author: "Emily Brontë" })
})
it ('GET /Books/201 w/ tail in URL plus CQL/CQN fragments in body' , async () => {
const {data:[b1]} = await GET ('/hcql/admin/Books where ID=201', {
data: cds.ql `SELECT title, author.name as author` .SELECT
})
expect(b1).to.deep.equal ({ title: "Wuthering Heights", author: "Emily Brontë" })
const {data:[b2]} = await GET ('/hcql/admin/Books where ID=201', {
headers: { 'Content-Type': 'text/plain' },
data: `{ title, author.name as author }`
})
expect(b2).to.deep.equal ({ title: "Wuthering Heights", author: "Emily Brontë" })
})
})

View File

@@ -0,0 +1,225 @@
@server = http://localhost:4004
GET {{server}}/odata/v4/admin/Authors?
&$select=ID,name
&$expand=books($select=ID,title)
&$count=true
###
#
# The basic variant expects a CQN object passed as an application/json body
# to a POST request. This is also the fastest one, as it doesn't need CQL parsing.
# Note: $count is returned in X-Total-Count response header
#
GET {{server}}/hcql/admin
Content-Type: application/json
# Accept-Language: de
{ "SELECT": {
"from": { "ref": [ "Authors" ] },
"columns": [
{ "ref": [ "name" ] },
{ "ref": [ "books" ], "expand": [
{ "ref": [ "ID" ] },
{ "ref": [ "title" ] }
]}
],
"count": true
}}
###
POST {{server}}/hcql/browse/submitOrder?book=201&quantity=2
Authorization: Basic alice:
###
POST {{server}}/hcql/browse/submitOrder
Authorization: Basic alice:
Content-Type: application/json
{
"book": 201,
"quantity": 2
}
###
GET {{server}}/hcql/browse/submitOrder?book=201&quantity=2
Authorization: Basic alice:
###
#
# Alternatively you can pass a CQL string as plain/text body
#
GET {{server}}/hcql/admin
Content-Type: text/plain
# X-Total-Count: true
SELECT from Authors { name, books { title }}
# SELECT from Books { title, currency }
###
#
# In addition we offer convenience slug routes...
# .e.g. /srv/entity routes
#
GET {{server}}/hcql/admin/Books
###
GET {{server}}/hcql/admin/Books/201
###
GET {{server}}/hcql/admin/Books { ID, title, author.name as author }
###
GET {{server}}/hcql/admin/Books order by stock desc
Content-Type: text/plain
{ title, stock }
###
GET {{server}}/hcql/admin/Books/201 { ID, title, author.name }
###
GET {{server}}/hcql/admin/Books/201 { ID, title, author{name} }
###
POST {{server}}/hcql/admin/Books?title=The Black Cat&author_ID=101
###
POST {{server}}/hcql/admin/Books?title=The Black Cat
Content-Type: application/json
{
"author_ID": 101
}
###
POST {{server}}/hcql/admin/Books
Content-Type: application/json
{
"title": "The Black Cat",
"author": { "ID": 101 }
}
###
PUT {{server}}/hcql/admin/Books/275?title=Catastrophe
###
PATCH {{server}}/hcql/admin/Books/275
Content-Type: application/json
{
"title": "Catastrophe"
}
###
GET {{server}}/hcql/admin/Authors { name, books { ID, title }}
###
GET {{server}}/hcql/admin/Books { ID, title, author.name as author } order by ID desc
###
// ------------------------------------
POST {{server}}/hcql/admin
Content-Type: application/json
{"SELECT": { "from": { "ref": ["Books"] }}}
###
POST {{server}}/hcql/admin
Content-Type: text/plain
SELECT from Authors {
name as author,
books {
title,
stock,
price,
currency { * }
}
}
where name like '%Bro%'
order by name asc
###
#
# Simple REST-style URLs as supported as well
#
GET {{server}}/hcql/admin/Books
###
GET {{server}}/hcql/admin/Books/201
###
#
# REST-style URLs can be combined with trailing CQL in the path, in plain
# text body, or with projections sent as application/json array
#
GET {{server}}/hcql/admin/Books order by stock desc
###
GET {{server}}/hcql/admin/Books { title as book, stock } order by stock desc
###
GET {{server}}/hcql/admin/Authors
Content-Type: text/plain
Accept-Language: fr
{
ID, name as author,
books {
title,
stock,
currency { * }
}
}
where name like '%Bro%'
order by name asc
###
GET {{server}}/hcql/admin/Books/201 { title, stock }
###
GET {{server}}/hcql/admin/Books order by stock desc
Content-Type: text/plain
{ title, stock }
###
#
# CQL adaptor also provides access to the underlying CSN schema
#
GET {{server}}/hcql/admin/$csn
###
#
# CQL adaptor also supports INSERTs, UPDATEs, DELETEs ...
#
POST {{server}}/hcql/admin
Content-Type: application/jsonin wonderland
{ "INSERT": {
"into": "Books",
"entries": [{
"title": "The Black Cat",
"author": { "ID": 150 }
}]
}}
###

View File

@@ -0,0 +1,26 @@
@server = http://localhost:4004
GET {{server}}/odata/v2/admin/Authors
Authorization: Basic alice:
###
GET {{server}}/odata/v2/admin/Authors?$select=ID,name&$expand=books($select=ID,title)
Authorization: Basic alice:
###
GET {{server}}/odata/v4/admin/Authors
Authorization: Basic alice:
###
GET {{server}}/odata/v4/admin/Authors?$select=ID,name&$expand=books($select=ID,title)
Authorization: Basic alice:
###
GET {{server}}/rest/admin/Authors
Authorization: Basic alice:
###
GET {{server}}/rest/admin/Authors?$select=ID,name&$expand=books($select=ID,title)
Authorization: Basic alice:
###

View File

@@ -0,0 +1,9 @@
@server = http://localhost:4004
GET {{server}}/rest/admin/Authors
Authorization: Basic alice:
###
GET {{server}}/rest/admin/Authors?$select=ID,name&$expand=books($select=ID,title)
Authorization: Basic alice:
###

View File

@@ -0,0 +1,4 @@
using { CatalogService, AdminService } from '@capire/bookstore';
annotate CatalogService with @hcql @odata @path:'browse' @requires:[];
annotate AdminService with @hcql @odata @path:'admin';

View File

@@ -1 +0,0 @@
require('./srv/server')

View File

@@ -7,11 +7,18 @@
"@capire/orders": "*", "@capire/orders": "*",
"@capire/common": "*", "@capire/common": "*",
"@capire/data-viewer": "*", "@capire/data-viewer": "*",
"@cap-js/hana": ">=1",
"@sap-cloud-sdk/http-client": "^4", "@sap-cloud-sdk/http-client": "^4",
"@sap-cloud-sdk/resilience": "^4", "@sap-cloud-sdk/resilience": "^4",
"@sap/cds": ">=5", "@sap/cds": ">=5",
"express": "^4.17.1", "express": "^4.17.1"
"@cap-js/hana": ">=1" },
"devDependencies": {
"@cap-js/sqlite": ">=1"
},
"scripts": {
"start": "cds-serve",
"watch": "cds watch"
}, },
"cds": { "cds": {
"requires": { "requires": {
@@ -24,11 +31,21 @@
"model": "@capire/orders" "model": "@capire/orders"
}, },
"messaging": true, "messaging": true,
"db": true "db": true,
"db-ext": {
"[development]": {
"model": "db/sqlite"
},
"[production]": {
"model": "db/hana"
}
}
}, },
"log": { "service": true } "log": { "service": true }
}, },
"scripts": { "sapux": [
"start": "cds-serve" "app/admin-authors",
} "app/admin-books",
"app/browse"
]
} }

2
bookstore/server.js Normal file
View File

@@ -0,0 +1,2 @@
require('./srv/mashup')
require('./srv/trees')

View File

@@ -1,195 +0,0 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="357px" height="283px" viewBox="-0.5 -0.5 357 283" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7VrZcqM4FP0av7q0L4+T9DIvU9VVeZhnFtlQwRYly7HTX98XgzBgOpNJG7eZGlKVwNECuudwdSSyoI+b41cXldlfNjXFgqD0uKCfFoQIIuF3BbzWACO6BtYuT2sInYGn/LupQRzQfZ6aXYPVkLe28HnZBxO73ZrE97DIOXvoV1vZIu0BZbQ2vceogKckKsxFtb/z1Gc1qsKwKvxPk6+zcGcsmvHFUfK8dna/be63IBQxXpdtotBRc9NdFqX20IHo5wV9dNb6+mxzfDRFFdd+zL78pLR9aGe2/j0NSN3gJSr2zbgXDCVRmTtTNSIi2pQL+rCNd9UfuC6g24fYwdnad5EAxNY+7zJbhgLoJT5XPg3Zv4YYw+jL6jQzx2htt1ClNC7fGG/cGf0WIAjOwyHLvXkqo6RqdgDhAZb5TQFXGE5X+dEELVXXu2fjkyri6FRYFI+2sO50c7paGZEkVSXv7LPplKRSxwi1JYF+0g6hG98m5C/GeXPsQE28vxoLD+9eoUpTSiSrm4QXQ9L6+nCWmW7kkXUUphosaoS9bns+8wsnDcXjdNNJ6Pa2an73fKvEjPMdK874zfimktyMb3Ztvp15yQ2k1rtnO+VGpWyMbUViKsRUbFOB+2xjfTO2+bXZTuxmA8TdPdkrXv1UuN36Dl4fYyIQp+NWImDhRbyBCMS1RWBdatwc3vjIqNVofheJMvFqKrKxEr+NbHlJ9pATs03/qOwwXCVFtNvlST/EvZBeBgiaN/GXp/LI+d71INRfTsdbgd3ZvUtML2FBp2vjew7FpMGd/yT4neDykeAGzJki8vlL39OPRby5wzebw/OeuSW4P3lzRPp91MNpmnWN9kVPYmD7+KCnOgoXPZ0k0A78XapQ81aFuHdVwKu75Iq2B+knAKrJslNKqfyYZIhmS4ZFewzXDQgvO6VC0Kn0pOetJzJzPTH+NtHX0hN7W7bX01PY4pmroNjMBcWHgppET3ygJzaZnIJlu5rl3e3Lssj/d73/wvXecp2LyUj+GFD4BJ2A4tD9M2hwys1oVtJC0miyRaoeEHjDbSk8sg85pwkgCLA7A4QsNI8pYOgp5CA7T+QpyGCqueIkMLLVOXdJibtSFAaqJVKcICw1ZIuw+dAuRzQoQSKGKFeSsY+aVIyXRGMmtSJIEBk+jrRrKw2yJpprwTAYmek86shm6qz0FL6Z3q1JxVpAClKnL8MaCc4HmUMuYaUDVhXWuUroD267EFClolhKLhHSlA1uwtmSUsGY4lphitRkarr6ruwqty7/T5ubCyczovl3f3Qjt3Q3974rO0gA/5hL6IjbEb/V3Ei9FFIpyBuKcKF0f5KozA3lEqYQLDimUvyCuaGQSSFzYMkoHtwFvI1gkGGwokwJWHBdKXvA5fkfQOrq5/+woZ9/AA==&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(0, 68, 85);">
<defs/>
<g>
<path d="M 199 202 L 249 202 L 269 242 L 249 282 L 199 282 L 179 242 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 242px; margin-left: 180px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
bookshop
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="246" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 199 101 L 249 101 L 269 141 L 249 181 L 199 181 L 179 141 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 141px; margin-left: 180px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
bookstore
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="145" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 286 48 L 336 48 L 356 88 L 336 128 L 286 128 L 266 88 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 88px; margin-left: 267px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
reviews
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="92" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 286 153 L 336 153 L 356 193 L 336 233 L 286 233 L 266 193 Z" fill="#f5f5f5" stroke="#666666" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 193px; margin-left: 267px;">
<div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
common
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="197" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 111 153 L 161 153 L 181 193 L 161 233 L 111 233 L 91 193 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 193px; margin-left: 92px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
orders
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="197" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 276.35 172.29 L 266.36 166.32" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 260.57 162.86 L 270.6 163.61 L 266.36 166.32 L 265.98 171.34 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 170.74 172.47 L 181.53 166.1" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 187.34 162.66 L 181.88 171.12 L 181.53 166.1 L 177.3 163.37 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 224 202 L 224 189.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 224 183.24 L 228.5 192.24 L 224 189.99 L 219.5 192.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 276.51 109.01 L 266.17 115.31" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 260.4 118.82 L 265.75 110.3 L 266.17 115.31 L 270.43 117.98 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 111 48 L 161 48 L 181 88 L 161 128 L 111 128 L 91 88 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 88px; margin-left: 92px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
suppliers
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="92" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 21 101 L 71 101 L 91 141 L 71 181 L 21 181 L 1 141 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 141px; margin-left: 2px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<b>
S/4
</b>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="145" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
S/4
</text>
</switch>
</g>
<path d="M 80.76 120.53 L 93.49 113.03" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 99.31 109.61 L 93.84 118.05 L 93.49 113.03 L 89.27 110.3 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 80.91 161.17 L 93.31 168.33" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 99.15 171.71 L 89.11 171.1 L 93.31 168.33 L 93.61 163.31 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 170.59 108.83 L 181.72 115.53" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 187.5 119.02 L 177.47 118.23 L 181.72 115.53 L 182.11 110.52 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 199 1 L 249 1 L 269 41 L 249 81 L 199 81 L 179 41 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 180px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
fiori
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="45" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 224 101 L 224 89.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 224 83.24 L 228.5 92.24 L 224 89.99 L 219.5 92.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display
</text>
</a>
</switch>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,212 +0,0 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="368px" height="282px" viewBox="-0.5 -0.5 368 282" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7Zpbc9o4FIB/DY9hdL88JqRJH9ppd9mZndk3YwvwxCBXmIT01+9xLNvYMaEl4ZIUeLB1JOt2viMdXXp0MFvduiCdfrWRSXoERaseve4RgpnU8Mglj4VEIF4IJi6OChGqBcP4p/FfltJlHJmFlxWizNoki9OmMLTzuQmzhixwzj40k41tEjUEaTAxzwTDMEieS/+No2xaSBWRtfyziSfTsmQsfINnQZnYt2QxDSL7sCain3p04KzNirfZamCSvPOa/XKzIbaqmDPz7Fc+mJDb2+X19NuX/778vEB/LX+gO3vhc7kPkqVvcI+IBPK7GuVVzh59P4gfy7yeV2M7zy4WT1q6hAQYp6Dpqzoe3ib588rau8XUpmVuUK1RGVeV4F5VxGWa+o6tsiDQx2n+OjWrYGLnkCo1Lp6ZzLha+r0UgQquHqZxZoZpEOafPQDDIJtmswRCOK9MvDIllUU4SQY2se6pPDoeGxGGIF9kzt6ZtZhI6hFCVUzJDvENvAlmcZKbxMDO4hAaMQzmC3h8HfoEZZm4DPtGoqceaGu+VKNxmVmtiTwJt8ZCg90jJPGxhPtPvFlSLYrwQw259uBO1/hWXhZ4s5pUOdfkwYuH7zdAJBtBXKTB/FWgvHlGowblmXVmHelm2i7wQVbUZQ3kNzGJDQUc30xUaLrNZKQ443syE+iCMJ5P/oFRiF7z/dgN0fK4dkP3bzevmwn+NvexgVl4fxPB0Lj7ODQf3IYiblTEumxIkREVYh829Hp7oaxlL0wd117YSw5PoWrop5nNTWcbs4XkOsiCo9NhMPAhu+jQQtLgndBBGT8uHfzUR9NvLjLuPJj+mYMpFidmLqLDXFqaNfPoMl+GQyhMgsUiDpuKanZzLoEvfCcW41ngska4pTA+yP/7U8/CLl1ots8oUM+JybavcEzU2HB4ruw1ZfIOZZYyZ5Igi++b2xRdGvYlfLcxtKxmCesmTKzc0ijzKBruP1vfV2jnRNqjuGzlVHTNs5yekKsavjuF8kxhNXO9MwoJl32uaPUjokkSlv21WEp3RJRI3GdYVD/JmsUQ0V+LFYIelF915rfaiPxg/MqXwXorfsXLZrJnfvWZ32of5mPxyw7DLzsuv+VR0+mu+obLNE3i88LvvPDrncYuGt58bvhqkxlCjdjJ8hMYNe48yRChMqPxRn7aeGznyTey45z3t/kRvOkvIHxkfMjZZaiNaKvPUE5Q78NpaDu95WS/Z6e3rMWhnIaug7czwpsS8pMiGANaEikOs5DUVJJy66tEizIgTyKGKFeSsR29XqxUn+j8CpQiSBApabMUwsCMiOZaMEw4P7DT23UQ9ufxi36R39NatmFJYYhV+aat1kjw1vQuSR+WapxjhrASmuyKr4ABFkvJJUK6OmuoCtF9SgVjimuFKVKHpffkD+puYuvifd9++9BLtfF4TDbcrRMjwfeyVDvMpSF87Mt2+HxwV4/p293v03JeCBd9wmE8Fk+neKp1+IZ1n2kYjyV4FAIcmJ237FBfMsEZlVIphHXLd4ElABIaE8byKyak5ePvPPxDsL4RXSSv75XTT/8D&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs/>
<g>
<path d="M 207 201 L 257 201 L 277 241 L 257 281 L 207 281 L 187 241 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 241px; margin-left: 188px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<b style="font-size: 11px;">
Bookshop
</b>
<br style="font-size: 11px;"/>
App
</div>
</div>
</div>
</foreignObject>
<text x="232" y="244" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Bookshop...
</text>
</switch>
</g>
<path d="M 207 102 L 257 102 L 277 142 L 257 182 L 207 182 L 187 142 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 145px; margin-left: 188px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
<span style="font-size: 11px;">
<b>
Bookstore
<br/>
</b>
</span>
App
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="232" y="148" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Bookstore...
</text>
</switch>
</g>
<path d="M 297 53 L 347 53 L 367 93 L 347 133 L 297 133 L 277 93 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 93px; margin-left: 278px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Reviews
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="322" y="96" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Reviews...
</text>
</switch>
</g>
<path d="M 297 150 L 347 150 L 367 190 L 347 230 L 297 230 L 277 190 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 190px; margin-left: 278px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<b>
Common
</b>
<br/>
Data
</div>
</div>
</div>
</foreignObject>
<text x="322" y="193" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Common...
</text>
</switch>
</g>
<path d="M 117 150 L 167 150 L 187 190 L 167 230 L 117 230 L 97 190 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 190px; margin-left: 98px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Orders
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="142" y="193" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Orders...
</text>
</switch>
</g>
<path d="M 286.47 171.05 L 273.81 164.3" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 268.51 161.47 L 277.45 161.71 L 273.81 164.3 L 273.69 168.77 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 177.53 171.05 L 190.19 164.3" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 195.49 161.47 L 190.31 168.77 L 190.19 164.3 L 186.55 161.71 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 232 201 L 232 189.12" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 232 183.12 L 236 191.12 L 232 189.12 L 228 191.12 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 286.63 112.26 L 273.62 119.34" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 268.35 122.21 L 273.47 114.87 L 273.62 119.34 L 277.29 121.9 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 117 53 L 167 53 L 187 93 L 167 133 L 117 133 L 97 93 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 93px; margin-left: 98px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Suppliers
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="142" y="96" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Suppliers...
</text>
</switch>
</g>
<path d="M 21 106 L 71 106 L 91 146 L 71 186 L 21 186 L 1 146 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 146px; margin-left: 2px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
S/4
</span>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="149" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle" font-weight="bold">
S/4
</text>
</switch>
</g>
<path d="M 81.27 126.53 L 100.5 115.91" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 105.76 113.01 L 100.69 120.38 L 100.5 115.91 L 96.82 113.37 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 82.61 162.78 L 98.92 170.25" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 104.37 172.75 L 95.43 173.06 L 98.92 170.25 L 98.77 165.79 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 177.37 112.26 L 190.38 119.34" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 195.65 122.21 L 186.71 121.9 L 190.38 119.34 L 190.53 114.87 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 207 1 L 257 1 L 277 41 L 257 81 L 207 81 L 187 41 Z" fill="#fff2cc" stroke="#d6b656" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 44px; margin-left: 188px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Fiori
</b>
<br style="font-size: 11px;"/>
App
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="232" y="47" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="11px" text-anchor="middle">
Fiori...
</text>
</switch>
</g>
<path d="M 232 102 L 232 88.12" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 232 82.12 L 236 90.12 L 232 88.12 L 228 90.12 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all"/>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display
</text>
</a>
</switch>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1 +0,0 @@
cds.requires.[hybrid].messaging.kind=file-based-messaging

View File

@@ -1 +0,0 @@
using from './db/common';

View File

@@ -1,43 +0,0 @@
{
"name": "@capire/fiori",
"version": "1.0.0",
"dependencies": {
"@capire/bookstore": "*",
"@sap/cds": ">=5",
"express": "^4.17.1"
},
"devDependencies": {
"@cap-js/sqlite": ">=1"
},
"scripts": {
"start": "cds-serve",
"watch": "cds watch"
},
"cds": {
"requires": {
"ReviewsService": {
"kind": "odata",
"model": "@capire/reviews"
},
"OrdersService": {
"kind": "odata",
"model": "@capire/orders"
},
"messaging": true,
"db": true,
"db-ext": {
"[development]": {
"model": "db/sqlite"
},
"[production]": {
"model": "db/hana"
}
}
}
},
"sapux": [
"app/admin-authors",
"app/admin-books",
"app/browse"
]
}

View File

@@ -52,7 +52,7 @@ module.exports = { DataService }
/** @returns {cds.Service} */ /** @returns {cds.Service} */
function findDataSource(dataSourceName, entityName) { function findDataSource(dataSourceName, entityName) {
for (let srv of Object.values(cds.services)) { // all connected services for (let srv of cds.service.providers) { // all connected services
if (!srv.name) continue // FIXME intermediate/pending in cds.services ? if (!srv.name) continue // FIXME intermediate/pending in cds.services ?
if (dataSourceName === srv.name || entityName.startsWith(srv.name+'.')) { if (dataSourceName === srv.name || entityName.startsWith(srv.name+'.')) {
log._debug && log.debug(`using ${srv.name} as data source`) log._debug && log.debug(`using ${srv.name} as data source`)

166
package-lock.json generated
View File

@@ -9,15 +9,7 @@
"version": "3.0.0", "version": "3.0.0",
"license": "SEE LICENSE IN LICENSE", "license": "SEE LICENSE IN LICENSE",
"workspaces": [ "workspaces": [
"bookshop", "*"
"bookstore",
"common",
"fiori",
"orders",
"reviews",
"shared-db",
"etc/data-viewer",
"etc/loggers"
], ],
"devDependencies": { "devDependencies": {
"@cap-js/cds-test": "^0" "@cap-js/cds-test": "^0"
@@ -48,6 +40,9 @@
"@sap-cloud-sdk/resilience": "^4", "@sap-cloud-sdk/resilience": "^4",
"@sap/cds": ">=5", "@sap/cds": ">=5",
"express": "^4.17.1" "express": "^4.17.1"
},
"devDependencies": {
"@cap-js/sqlite": ">=1"
} }
}, },
"common": { "common": {
@@ -57,14 +52,14 @@
"@sap/cds": "*" "@sap/cds": "*"
} }
}, },
"etc/data-viewer": { "inspectr": {
"name": "@capire/data-viewer", "name": "@capire/data-viewer",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@sap/cds": ">=5.0.4" "@sap/cds": ">=5.0.4"
} }
}, },
"etc/loggers": { "loggers": {
"name": "@capire/loggers", "name": "@capire/loggers",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
@@ -72,23 +67,12 @@
"express": "^4.17.1" "express": "^4.17.1"
} }
}, },
"fiori": {
"name": "@capire/fiori",
"version": "1.0.0",
"dependencies": {
"@capire/bookstore": "*",
"@sap/cds": ">=5",
"express": "^4.17.1"
},
"devDependencies": {
"@cap-js/sqlite": ">=1"
}
},
"node_modules/@cap-js/cds-test": { "node_modules/@cap-js/cds-test": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/@cap-js/cds-test/-/cds-test-0.4.0.tgz", "resolved": "https://registry.npmjs.org/@cap-js/cds-test/-/cds-test-0.4.0.tgz",
"integrity": "sha512-l8Ad/rV5qXIjU9qyA3twcKDYUnT1Ru1402BHhjnMjeYD9GeCmoj/0KrRGFbQIW63zAbs3QFya9X4GMGd0qYesA==", "integrity": "sha512-l8Ad/rV5qXIjU9qyA3twcKDYUnT1Ru1402BHhjnMjeYD9GeCmoj/0KrRGFbQIW63zAbs3QFya9X4GMGd0qYesA==",
"dev": true, "dev": true,
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"axios": "^1", "axios": "^1",
"chai": "^4.4.1", "chai": "^4.4.1",
@@ -110,6 +94,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@cap-js/db-service/-/db-service-2.2.0.tgz", "resolved": "https://registry.npmjs.org/@cap-js/db-service/-/db-service-2.2.0.tgz",
"integrity": "sha512-C5n8Qy8MwOGWjpXS44CskaEZt8YKrEEs4AtJyBSfJ6+aKMu/ynqpXh0Up4Ql0XX2Frq2PwNU8Ohai/04wxd46g==", "integrity": "sha512-C5n8Qy8MwOGWjpXS44CskaEZt8YKrEEs4AtJyBSfJ6+aKMu/ynqpXh0Up4Ql0XX2Frq2PwNU8Ohai/04wxd46g==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"generic-pool": "^3.9.0" "generic-pool": "^3.9.0"
}, },
@@ -121,6 +106,7 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/@cap-js/hana/-/hana-2.1.1.tgz", "resolved": "https://registry.npmjs.org/@cap-js/hana/-/hana-2.1.1.tgz",
"integrity": "sha512-4N/ByOd1N++7IEVwoSKyIqEXEzuAJE1qhpWhr3JM4LPoeCpvlv+Eki/YLIvCB06O7/PO8d2569Emjml/TwaJhQ==", "integrity": "sha512-4N/ByOd1N++7IEVwoSKyIqEXEzuAJE1qhpWhr3JM4LPoeCpvlv+Eki/YLIvCB06O7/PO8d2569Emjml/TwaJhQ==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@cap-js/db-service": "^2.1.1", "@cap-js/db-service": "^2.1.1",
"hdb": "^0.19.5" "hdb": "^0.19.5"
@@ -140,6 +126,7 @@
"resolved": "https://registry.npmjs.org/@cap-js/sqlite/-/sqlite-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@cap-js/sqlite/-/sqlite-2.0.2.tgz",
"integrity": "sha512-oNg2f56sfELshyp0eSmYYwG1lt4Zmc135sLIzS8iykHdRVxxJpTrPj0jx0Y4Hc6sfC9u25LRXVu/ZKqjm9Yu+Q==", "integrity": "sha512-oNg2f56sfELshyp0eSmYYwG1lt4Zmc135sLIzS8iykHdRVxxJpTrPj0jx0Y4Hc6sfC9u25LRXVu/ZKqjm9Yu+Q==",
"dev": true, "dev": true,
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@cap-js/db-service": "^2", "@cap-js/db-service": "^2",
"better-sqlite3": "^12.0.0" "better-sqlite3": "^12.0.0"
@@ -161,15 +148,11 @@
"link": true "link": true
}, },
"node_modules/@capire/data-viewer": { "node_modules/@capire/data-viewer": {
"resolved": "etc/data-viewer", "resolved": "inspectr",
"link": true
},
"node_modules/@capire/fiori": {
"resolved": "fiori",
"link": true "link": true
}, },
"node_modules/@capire/loggers": { "node_modules/@capire/loggers": {
"resolved": "etc/loggers", "resolved": "loggers",
"link": true "link": true
}, },
"node_modules/@capire/orders": { "node_modules/@capire/orders": {
@@ -205,13 +188,16 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "9.24.0", "version": "9.31.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
"integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://eslint.org/donate"
} }
}, },
"node_modules/@sap-cloud-sdk/connectivity": { "node_modules/@sap-cloud-sdk/connectivity": {
@@ -271,6 +257,7 @@
"version": "9.1.0", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/@sap/cds/-/cds-9.1.0.tgz", "resolved": "https://registry.npmjs.org/@sap/cds/-/cds-9.1.0.tgz",
"integrity": "sha512-i5bAVbFzi1uN11O4U6SdPKzYDDxc+YDSWMiqt1ryxT0WYrrehJPg5pJQjy4AH1EgRIqa3eqK2RfmHS6SgkBOyg==", "integrity": "sha512-i5bAVbFzi1uN11O4U6SdPKzYDDxc+YDSWMiqt1ryxT0WYrrehJPg5pJQjy4AH1EgRIqa3eqK2RfmHS6SgkBOyg==",
"license": "SEE LICENSE IN LICENSE",
"dependencies": { "dependencies": {
"@sap/cds-compiler": "^6", "@sap/cds-compiler": "^6",
"@sap/cds-fiori": "^2", "@sap/cds-fiori": "^2",
@@ -301,6 +288,7 @@
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sap/cds-compiler/-/cds-compiler-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@sap/cds-compiler/-/cds-compiler-6.1.0.tgz",
"integrity": "sha512-s71fsxDZKqHn2xvoqoNst54K/BkBzCpiU+8xc0t3nMDXmsLzSC3VfygZGwGAZD8fkxUnXh8oL2XLHWKWcvcdNg==", "integrity": "sha512-s71fsxDZKqHn2xvoqoNst54K/BkBzCpiU+8xc0t3nMDXmsLzSC3VfygZGwGAZD8fkxUnXh8oL2XLHWKWcvcdNg==",
"license": "SEE LICENSE IN LICENSE",
"bin": { "bin": {
"cdsc": "bin/cdsc.js", "cdsc": "bin/cdsc.js",
"cdshi": "bin/cdshi.js", "cdshi": "bin/cdshi.js",
@@ -314,15 +302,16 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@sap/cds-fiori/-/cds-fiori-2.0.1.tgz", "resolved": "https://registry.npmjs.org/@sap/cds-fiori/-/cds-fiori-2.0.1.tgz",
"integrity": "sha512-KZVLWXndydgqdlao8OL1gtgd/XMgBdiKBmmgwGpBL1y4S21FOXglnWh6d3bnSZL/qwR3z50D+0PoGghjhayF0Q==", "integrity": "sha512-KZVLWXndydgqdlao8OL1gtgd/XMgBdiKBmmgwGpBL1y4S21FOXglnWh6d3bnSZL/qwR3z50D+0PoGghjhayF0Q==",
"license": "SEE LICENSE IN LICENSE",
"peerDependencies": { "peerDependencies": {
"@sap/cds": ">=8", "@sap/cds": ">=8",
"express": ">=4" "express": ">=4"
} }
}, },
"node_modules/@sap/xsenv": { "node_modules/@sap/xsenv": {
"version": "5.5.0", "version": "5.6.1",
"resolved": "https://registry.npmjs.org/@sap/xsenv/-/xsenv-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@sap/xsenv/-/xsenv-5.6.1.tgz",
"integrity": "sha512-+FIpnXjDrgtJaN6AxjDRIc5ONd4Yt5UarCqqzRiZjvJaknnkT+b6/ho/va/rg8UdiCAVxn8c4vMVhgjXGc/gmQ==", "integrity": "sha512-4pDpsYLNJsLUBWtTSG+TJ8ul5iY0dWDyJgTy2H/WZGZww9CSPLP/39x+syDDTjkggsmZAlo9t7y9TiXMmtAunw==",
"license": "SEE LICENSE IN LICENSE file", "license": "SEE LICENSE IN LICENSE file",
"dependencies": { "dependencies": {
"debug": "4.4.0", "debug": "4.4.0",
@@ -357,9 +346,10 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@sap/xssec": { "node_modules/@sap/xssec": {
"version": "4.8.0", "version": "4.9.0",
"resolved": "https://registry.npmjs.org/@sap/xssec/-/xssec-4.8.0.tgz", "resolved": "https://registry.npmjs.org/@sap/xssec/-/xssec-4.9.0.tgz",
"integrity": "sha512-9R9nfx6LK53B938CeUY4aIrH5kcxxkdpiQARtzH5uLFYDzUW08n5LPRkoCxR41zrIDXdWQFmQ/Xd7n4Vv+CDlQ==", "integrity": "sha512-x2f1AvS9KDs3djtDsRgH4Md3Ze5vc2NZHAlpCf+oRokWaQCmMNmS57DE6Zm80IVCCzo1mr8VtSrjWMPTshfUpw==",
"license": "SAP DEVELOPER LICENSE AGREEMENT",
"dependencies": { "dependencies": {
"debug": "^4.3.4", "debug": "^4.3.4",
"jwt-decode": "^4" "jwt-decode": "^4"
@@ -369,9 +359,9 @@
} }
}, },
"node_modules/@sap/xssec/node_modules/debug": { "node_modules/@sap/xssec/node_modules/debug": {
"version": "4.4.0", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "^2.1.3"
@@ -428,7 +418,8 @@
"node_modules/argparse": { "node_modules/argparse": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
}, },
"node_modules/array-flatten": { "node_modules/array-flatten": {
"version": "1.1.1", "version": "1.1.1",
@@ -477,9 +468,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.8.4", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
@@ -505,7 +496,8 @@
"type": "consulting", "type": "consulting",
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
] ],
"license": "MIT"
}, },
"node_modules/better-sqlite3": { "node_modules/better-sqlite3": {
"version": "12.2.0", "version": "12.2.0",
@@ -513,6 +505,7 @@
"integrity": "sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==", "integrity": "sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT",
"dependencies": { "dependencies": {
"bindings": "^1.5.0", "bindings": "^1.5.0",
"prebuild-install": "^7.1.1" "prebuild-install": "^7.1.1"
@@ -526,6 +519,7 @@
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"file-uri-to-path": "1.0.0" "file-uri-to-path": "1.0.0"
} }
@@ -535,6 +529,7 @@
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"buffer": "^5.5.0", "buffer": "^5.5.0",
"inherits": "^2.0.4", "inherits": "^2.0.4",
@@ -584,6 +579,7 @@
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"base64-js": "^1.3.1", "base64-js": "^1.3.1",
"ieee754": "^1.1.13" "ieee754": "^1.1.13"
@@ -669,6 +665,7 @@
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz", "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz",
"integrity": "sha512-K3d+KmqdS5XKW5DWPd5sgNffL3uxdDe+6GdnJh3AYPhwnBGRY5urfvfcbRtWIvvpz+KxkL9FeBB6MZewLUNwug==", "integrity": "sha512-K3d+KmqdS5XKW5DWPd5sgNffL3uxdDe+6GdnJh3AYPhwnBGRY5urfvfcbRtWIvvpz+KxkL9FeBB6MZewLUNwug==",
"deprecated": "functionality of this lib is built-in to chai now. see more details here: https://github.com/debitoor/chai-subset/pull/85",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -708,7 +705,8 @@
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true "dev": true,
"license": "ISC"
}, },
"node_modules/clone": { "node_modules/clone": {
"version": "2.1.2", "version": "2.1.2",
@@ -850,6 +848,7 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"mimic-response": "^3.1.0" "mimic-response": "^3.1.0"
}, },
@@ -878,6 +877,7 @@
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=4.0.0"
} }
@@ -915,6 +915,7 @@
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
"dev": true, "dev": true,
"license": "Apache-2.0",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@@ -968,6 +969,7 @@
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"once": "^1.4.0" "once": "^1.4.0"
} }
@@ -1037,6 +1039,7 @@
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"dev": true, "dev": true,
"license": "(MIT OR WTFPL)",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -1106,7 +1109,8 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/finalhandler": { "node_modules/finalhandler": {
"version": "1.3.1", "version": "1.3.1",
@@ -1153,14 +1157,15 @@
} }
}, },
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.2", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0", "es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
}, },
"engines": { "engines": {
@@ -1189,7 +1194,8 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.2", "version": "1.1.2",
@@ -1260,7 +1266,8 @@
"version": "0.0.0", "version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/gopd": { "node_modules/gopd": {
"version": "1.2.0", "version": "1.2.0",
@@ -1380,7 +1387,8 @@
"type": "consulting", "type": "consulting",
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
] ],
"license": "BSD-3-Clause"
}, },
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
@@ -1392,7 +1400,8 @@
"version": "1.3.8", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true "dev": true,
"license": "ISC"
}, },
"node_modules/ipaddr.js": { "node_modules/ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
@@ -1425,6 +1434,7 @@
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"license": "MIT",
"dependencies": { "dependencies": {
"argparse": "^2.0.1" "argparse": "^2.0.1"
}, },
@@ -1461,12 +1471,12 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/jwa": { "node_modules/jwa": {
"version": "1.4.1", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"buffer-equal-constant-time": "1.0.1", "buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11", "ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
@@ -1645,6 +1655,7 @@
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@@ -1657,6 +1668,7 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true, "dev": true,
"license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
@@ -1665,7 +1677,8 @@
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/ms": { "node_modules/ms": {
"version": "2.0.0", "version": "2.0.0",
@@ -1677,7 +1690,8 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/negotiator": { "node_modules/negotiator": {
"version": "0.6.3", "version": "0.6.3",
@@ -1693,6 +1707,7 @@
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
"integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"semver": "^7.3.5" "semver": "^7.3.5"
}, },
@@ -1741,6 +1756,7 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true, "dev": true,
"license": "ISC",
"dependencies": { "dependencies": {
"wrappy": "1" "wrappy": "1"
} }
@@ -1755,12 +1771,12 @@
} }
}, },
"node_modules/opossum": { "node_modules/opossum": {
"version": "8.4.0", "version": "8.5.0",
"resolved": "https://registry.npmjs.org/opossum/-/opossum-8.4.0.tgz", "resolved": "https://registry.npmjs.org/opossum/-/opossum-8.5.0.tgz",
"integrity": "sha512-YYamqKu48bZCSTJKSWLLO4SSk8tKN2Gg2z1sJZVzHJYVObMO/xQpIzAh6re9HCMHRdB1dJvBjJH18DW7xYOicg==", "integrity": "sha512-LZNvs+p9/ZbG4oN6unnjh4hTxkB0dyHKI2p7azVt8w+//GKDpfHss6WR7KebbpzGEssYwtSd8Mvwxqcmxg10NA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
"node": "^22 || ^21 || ^20 || ^18 || ^16" "node": "^24 || ^22 || ^21 || ^20 || ^18 || ^16"
} }
}, },
"node_modules/parseurl": { "node_modules/parseurl": {
@@ -1793,6 +1809,7 @@
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"detect-libc": "^2.0.0", "detect-libc": "^2.0.0",
"expand-template": "^2.0.3", "expand-template": "^2.0.3",
@@ -1838,6 +1855,7 @@
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
"once": "^1.3.1" "once": "^1.3.1"
@@ -1887,6 +1905,7 @@
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true, "dev": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": { "dependencies": {
"deep-extend": "^0.6.0", "deep-extend": "^0.6.0",
"ini": "~1.3.0", "ini": "~1.3.0",
@@ -1956,9 +1975,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.7.1", "version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC", "license": "ISC",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
@@ -2117,7 +2136,8 @@
"type": "consulting", "type": "consulting",
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
] ],
"license": "MIT"
}, },
"node_modules/simple-get": { "node_modules/simple-get": {
"version": "4.0.1", "version": "4.0.1",
@@ -2138,6 +2158,7 @@
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"decompress-response": "^6.0.0", "decompress-response": "^6.0.0",
"once": "^1.3.1", "once": "^1.3.1",
@@ -2185,6 +2206,7 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -2206,6 +2228,7 @@
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
"integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2", "mkdirp-classic": "^0.5.2",
@@ -2218,6 +2241,7 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"bl": "^4.0.3", "bl": "^4.0.3",
"end-of-stream": "^1.4.1", "end-of-stream": "^1.4.1",
@@ -2258,6 +2282,7 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true, "dev": true,
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
}, },
@@ -2381,7 +2406,8 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true "dev": true,
"license": "ISC"
}, },
"orders": { "orders": {
"name": "@capire/orders", "name": "@capire/orders",

View File

@@ -5,15 +5,7 @@
"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",
"workspaces": [ "workspaces": [
"bookshop", "*"
"bookstore",
"common",
"fiori",
"orders",
"reviews",
"shared-db",
"etc/data-viewer",
"etc/loggers"
], ],
"devDependencies": { "devDependencies": {
"@cap-js/cds-test": "^0" "@cap-js/cds-test": "^0"
@@ -22,11 +14,10 @@
"start": "cds watch bookshop --open http://localhost:4004", "start": "cds watch bookshop --open http://localhost:4004",
"bookstore": "cds watch bookstore", "bookstore": "cds watch bookstore",
"bookshop": "cds watch bookshop", "bookshop": "cds watch bookshop",
"fiori": "cds watch fiori",
"orders": "cds watch orders", "orders": "cds watch orders",
"reviews": "cds watch reviews", "reviews": "cds watch reviews",
"lint": "npx eslint", "lint": "npx eslint",
"test": "chest test", "test": "chest",
"jest": "npx jest", "jest": "npx jest",
"mocha": "npx mocha", "mocha": "npx mocha",
"node:test": "node --test", "node:test": "node --test",

View File

@@ -2,7 +2,7 @@
# 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](readme/samples.md#all-in-one-monorepo).
![](https://github.com/SAP-samples/cloud-cap-samples/workflows/CI/badge.svg) ![](https://github.com/SAP-samples/cloud-cap-samples/workflows/CI/badge.svg)
@@ -21,7 +21,7 @@ npm start
After download and setup this starts the bookshop server and opens a browser window on _http://localhost:4004_ looking like that: After download and setup this starts the bookshop server and opens a browser window on _http://localhost:4004_ looking like that:
<p align="center"> <p align="center">
<img width=480 src="etc/index-html.png" alt="bookshop showing up in browser" /> <img width=480 src="readme/index-html.png" alt="bookshop showing up in browser" />
</p> </p>
Click on the *[/vue](http:/localhost:4004/vue)* link at the top to display the bookshop app (when asked to log in, type `alice` as user and leave the password field blank). Click on the *[/vue](http:/localhost:4004/vue)* link at the top to display the bookshop app (when asked to log in, type `alice` as user and leave the password field blank).
@@ -35,14 +35,11 @@ After the jumpstart, have a look into the enclosed sub folders/projects, which a
- [orders](orders) - a generic reuse service - [orders](orders) - a generic reuse service
- [common](common) - a reuse content package - [common](common) - a reuse content package
- [bookstore](bookstore) - a composite app of the above - [bookstore](bookstore) - a composite app of the above
- [fiori](fiori) - Fiori elements UIs for the bookstore
- [etc/*](etc) - Plugins adding cross-cutting concerns
- [test](test) - Tests for all the above
> _see also [samples.md](samples.md)_ > _see also [samples.md](readme/samples.md)_
<p align="center"> <p align="center">
<img width=480 src="etc/samples.drawio.svg"> <img width=480 src="readme/samples.drawio.svg">
</p> </p>
## Get Help ## Get Help

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

215
readme/dark.drawio.svg Normal file
View File

@@ -0,0 +1,215 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" style="background: #045; background-color: light-dark(#045, #000000);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="357px" height="236px" viewBox="-0.5 -0.5 357 236" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7VnLjqM4FP2abCO/H8upmn5sWmqpFrPmcRNQkRgZp5Karx8TMAFCl3pKIROkIYvYxy98z/H1tVnR593pm43K7IdJoVgRlJ5W9M8VIRhj7f9q5L1BuEYNsLV52kA94CX/G9qWAT3kKVQt1kDOmMLl5RBMzH4PiRtgkbXmOKy2MUU6AMpoC4PXqIGXJCrgqtpfeeqyBlVEXvDvkG+zMDIW7YTjKHndWnPYt+OtCEWMN2W7KHTUDlplUWqOPYh+WdFna4xrUrvTMxS1YYc2+/qL0u6lLezd7zQgTYO3qDi0814xlERlbqFuRES0K1f0aR9X9Z/PF77bp9j61Nb1kQDExrxWmSlDge8lvlQ+T9m9Bxv72Zd1MoNTtDV7X6UEm+/Agb2gPwPkjfN0zHIHL2WU1M2OXnkey9yu8Dnsk5v8BEFLdb56BZfUFkfnwqJ4NoWx58HpZgMiSepKzppX6JWkUscIdSWBftJNoW/f1uRvYB2celBr729g/Mvbd1+lLSWSNU3ahcEkbfLHi8zCWsl6ClMtFrXC3nY9X/j1iZbiabrpLHQ7Uzd/eL5VAtN8x4ozfje+qSR345vdmm8Lbzl41/rwbKccVMqm2FYkpkLMxTYVeMh22AfvwDa/NduJ2e08cQ9P9obXvxo3e9fDm2dKBOL83EsELCzEO4hA3FoExqZgl7DiI1CbSf8uEgXxZi6ysRL/GdnymuwxJ7BP/6jDYZ9Liqiq8mRo4oFJrw3km7f2l+fyyLpBfmTqr+fnI8NW5mATGDgs3+kW3CBCgTRE578wfs+4fMK4AbNQRC5/G8b0UxZvR/hpcv++F24JHm7eHJFhH8102mb9QPuqJzEK+/iop8YKVz2dJdBN/LdUoZatCvHoqvBLd80V7R4ydABUk3WvlFL5OckQzdYMi+4ZnxsQXvdKhaBz6UkvW09k4Xpi/GOib6Un9rFsb6encMWzVEGxhQuKjwU1i574SE9sNjmFkO1mIW91KMsi/z/q/RdR7z3PuZhM+I8RhS++E6849PgMAk45THolLSSNZjuk6hGBd7yWwhP3kEvaAIIA+ztA8ELL2ALGMYUceeeZYgoy2mpuuAlMXHUuXVLioRSFPdUSKU4Qltp7i3D50B1HtFeCRAxRriRjnw1SMV4TjZnUiiBBZPg40p2ttJc10VwLhn0gM1+MOnGZuig9hW+mDxukYi28C1L1hZnWSHA+8hxy7U86PlT151wl9CevXYhXpaJYSi4R0pSNBuFsTalgTHGtMEXqRmry2csn3Kb65SM5/fIP&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs/>
<rect fill="#045" width="100%" height="100%" x="0" y="0" style="fill: light-dark(rgb(0, 68, 85), rgb(0, 0, 0));"/>
<g>
<g>
<path d="M 199 155 L 249 155 L 269 195 L 249 235 L 199 235 L 179 195 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 230, 204), rgb(54, 33, 10)); stroke: light-dark(rgb(215, 155, 0), rgb(153, 101, 0));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 195px; margin-left: 180px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
bookshop
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="199" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 199 54 L 249 54 L 269 94 L 249 134 L 199 134 L 179 94 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(248, 206, 204), rgb(81, 45, 43)); stroke: light-dark(rgb(184, 84, 80), rgb(215, 129, 126));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 94px; margin-left: 180px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
bookstore
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="98" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 286 1 L 336 1 L 356 41 L 336 81 L 286 81 L 266 41 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(213, 232, 212), rgb(31, 47, 30)); stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 267px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
reviews
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="45" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 286 106 L 336 106 L 356 146 L 336 186 L 286 186 L 266 146 Z" fill="#f5f5f5" stroke="#666666" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(245, 245, 245), rgb(26, 26, 26)); stroke: light-dark(rgb(102, 102, 102), rgb(149, 149, 149));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 146px; margin-left: 267px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #333333; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#333333, #c1c1c1); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
common
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="150" fill="#333333" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 111 106 L 161 106 L 181 146 L 161 186 L 111 186 L 91 146 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(218, 232, 252), rgb(29, 41, 59)); stroke: light-dark(rgb(108, 142, 191), rgb(92, 121, 163));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 146px; margin-left: 92px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
orders
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="150" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 276.35 125.29 L 266.36 119.32" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 260.57 115.86 L 270.6 116.61 L 266.36 119.32 L 265.98 124.34 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 170.74 125.47 L 181.53 119.1" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 187.34 115.66 L 181.88 124.12 L 181.53 119.1 L 177.3 116.37 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 224 155 L 224 142.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 224 136.24 L 228.5 145.24 L 224 142.99 L 219.5 145.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 276.51 62.01 L 266.17 68.31" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 260.4 71.82 L 265.75 63.3 L 266.17 68.31 L 270.43 70.98 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 111 1 L 161 1 L 181 41 L 161 81 L 111 81 L 91 41 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(218, 232, 252), rgb(29, 41, 59)); stroke: light-dark(rgb(108, 142, 191), rgb(92, 121, 163));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 92px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
suppliers
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="45" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
</g>
<g>
<path d="M 21 54 L 71 54 L 91 94 L 71 134 L 21 134 L 1 94 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(225, 213, 231), rgb(57, 47, 63)); stroke: light-dark(rgb(150, 115, 166), rgb(149, 119, 163));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 94px; margin-left: 2px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<b>
S/4
</b>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="98" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">
S/4
</text>
</switch>
</g>
</g>
<g>
<path d="M 80.76 73.53 L 93.49 66.03" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 99.31 62.61 L 93.84 71.05 L 93.49 66.03 L 89.27 63.3 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 80.91 114.17 L 93.31 121.33" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 99.15 124.71 L 89.11 124.1 L 93.31 121.33 L 93.61 116.31 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
<g>
<path d="M 170.59 61.83 L 181.72 68.53" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
<path d="M 187.5 72.02 L 177.47 71.23 L 181.72 68.53 L 182.11 63.52 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 255, 255), rgb(18, 18, 18)); stroke: light-dark(rgb(255, 255, 255), rgb(18, 18, 18));"/>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display
</text>
</a>
</switch>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

228
readme/samples.drawio.svg Normal file
View File

@@ -0,0 +1,228 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="368px" height="230px" viewBox="-0.5 -0.5 368 230" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7ZpLc9o6GIZ/Dcsw1l1aBtKmi3Z64cycmbMTtsCeGOTKJpD++iPHkrEdE9okBJICC6xXsm7f8+nKAI0Xm2sjs/iLjlQ6gEG0GaCrAYQAAGF/SuWuUogIKmFukqiSGsIk+aXcm15dJZHKnVZJhdZpkWRtMdTLpQqLliaN0et2splOo5aQybl6IExCmT5U/02iIq5UDtlW/6SSeexLBtQ1eCF9YteSPJaRXjck9GGAxkbronpabMYqLTuv3S8fd8TWFTNqWfzOC3N4fb26ir9+/u/zr4vg++pncKMvXC63Ml25Bg8gTW1+o2lZ5eLO9QP9uSrrOZrpZXGR31vp0iYAILOWHm3j7dO8/B1pfZPHOvO52WpNfVxdgnlWEZdZ5jq2zgLaPs7Kx1ht5FwvbapMmWShCmW26jcvWROM1nFSqEkmw/K1tWXYanGxSG0IlJVJNspTWYXTdKxTbe7LQ7OZomFo9bww+kY1YiImpkFQx3h2oGvgR7lI0tIlxnqRhLYRE7nM7c+XiUvgywQ+7BoZ3PdA1/LejMoUatOQHAnXStsGmzubxMVC4l5xbokErcLrLeTeU+MG39xp0rnVvM55S559cPD9AYhwJ4h5JpfPAuXFM5q2KC+0UU2k22n7wLdaVZcGyC/iEjsKOL6b8FD1u8mUE0wO5Ca2C8JkOf/HjkLoihzGb6Bgx/UbdHi/ed5M8EPdJsrOwoebCCbK3Caheuc+FBHFI9znQxxOEaWH8KHn+wvCHX/B/Lj+gh9b8FSmtv200KXr7GO2Uq5kIY9OhwKWD9ZHh6AMyTdCB8LkuHSQUx9Nv5pImfNg+ncOpoCemLvQHnfpWFYto8tyG25DYSrzPAnbhmp3c6nYN1wnVuOZNEUr3DEYGZffw5kn1ysTqv0ziq3nXBX7dzgqah04PDR2w5ikx5heMyqVRXLbPqbos7Ar4ZtObMu2LAHRhgn7Iw2fR9Vw91rzXKGbE+yO4qyTU9U1D3K6R65u+NMpZGcK65nrjVEICRsSjuoPpG2SABs2YhF6IqKQgSEGtP4w3C4G0mEjllL0qvzyM7/1QeQ745c9DtZL8Usfd5MD8yvO/NbnMO+LX/w6/OLj8uuvmk531zdZZVmanDd+543f4DRO0cDue8Nnu8zE1gifLD9S8VnvTQYNuZrOdvLTxWM/T66RPfe8f8wPJe31QgCOjA88Lxm2TrR3zeAnqLexaOguev1kf+BFr6/Fay0a+i7ezgjvSkhOimBg0WIBJ3YWYgIx6I++PFoIW/JYgANEOMP4iatewPkQCoCZ4DCgkDHULgVi60ZQEEExgIS88qK37yLs7+M3+E1+T2vbBhiyQywvD22FCCjpTO8MDu1WjRCAA8CpgE/Fl9oBFjBGWBCI+q6hLkQMEaIYcyI4QAF/IXptcPuXuCr59o+F6MP/&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs/>
<g>
<g>
<path d="M 207 149 L 257 149 L 277 189 L 257 229 L 207 229 L 187 189 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(255, 230, 204), rgb(54, 33, 10)); stroke: light-dark(rgb(215, 155, 0), rgb(153, 101, 0));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 189px; margin-left: 188px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<b style="font-size: 11px;">
Bookshop
</b>
<br style="font-size: 11px;"/>
App
</div>
</div>
</div>
</foreignObject>
<text x="232" y="192" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Bookshop...
</text>
</switch>
</g>
</g>
<g>
<path d="M 207 50 L 257 50 L 277 90 L 257 130 L 207 130 L 187 90 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(248, 206, 204), rgb(81, 45, 43)); stroke: light-dark(rgb(184, 84, 80), rgb(215, 129, 126));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 93px; margin-left: 188px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<span style="font-size: 11px;">
<span style="font-size: 11px;">
<b>
Bookstore
<br/>
</b>
</span>
App
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="232" y="96" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Bookstore...
</text>
</switch>
</g>
</g>
<g>
<path d="M 297 1 L 347 1 L 367 41 L 347 81 L 297 81 L 277 41 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(213, 232, 212), rgb(31, 47, 30)); stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 278px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Reviews
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="322" y="44" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Reviews...
</text>
</switch>
</g>
</g>
<g>
<path d="M 297 98 L 347 98 L 367 138 L 347 178 L 297 178 L 277 138 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(225, 213, 231), rgb(57, 47, 63)); stroke: light-dark(rgb(150, 115, 166), rgb(149, 119, 163));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 138px; margin-left: 278px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<b>
Common
</b>
<br/>
Data
</div>
</div>
</div>
</foreignObject>
<text x="322" y="141" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Common...
</text>
</switch>
</g>
</g>
<g>
<path d="M 117 98 L 167 98 L 187 138 L 167 178 L 117 178 L 97 138 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(213, 232, 212), rgb(31, 47, 30)); stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 138px; margin-left: 98px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Orders
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="142" y="141" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Orders...
</text>
</switch>
</g>
</g>
<g>
<path d="M 286.47 119.05 L 273.81 112.3" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 268.51 109.47 L 277.45 109.71 L 273.81 112.3 L 273.69 116.77 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 177.53 119.05 L 190.19 112.3" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 195.49 109.47 L 190.31 116.77 L 190.19 112.3 L 186.55 109.71 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 232 149 L 232 137.12" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 232 131.12 L 236 139.12 L 232 137.12 L 228 139.12 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 286.63 60.26 L 273.62 67.34" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 268.35 70.21 L 273.47 62.87 L 273.62 67.34 L 277.29 69.9 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 117 1 L 167 1 L 187 41 L 167 81 L 117 81 L 97 41 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(213, 232, 212), rgb(31, 47, 30)); stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 98px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<span style="font-size: 11px;">
<b style="font-size: 11px;">
Suppliers
</b>
<br style="font-size: 11px;"/>
Service
<br style="font-size: 11px;"/>
</span>
</div>
</div>
</div>
</foreignObject>
<text x="142" y="44" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle">
Suppliers...
</text>
</switch>
</g>
</g>
<g>
<path d="M 21 54 L 71 54 L 91 94 L 71 134 L 21 134 L 1 94 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(218, 232, 252), rgb(29, 41, 59)); stroke: light-dark(rgb(108, 142, 191), rgb(92, 121, 163));"/>
</g>
<g>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 94px; margin-left: 2px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
<div style="display: inline-block; font-size: 11px; font-family: &quot;Comic Sans MS&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
<span style="font-size: 11px;">
S/4
</span>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="97" fill="light-dark(#000000, #ffffff)" font-family="&quot;Comic Sans MS&quot;" font-size="11px" text-anchor="middle" font-weight="bold">
S/4
</text>
</switch>
</g>
</g>
<g>
<path d="M 81.27 74.53 L 100.5 63.91" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 105.76 61.01 L 100.69 68.38 L 100.5 63.91 L 96.82 61.37 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 82.61 110.78 L 98.92 118.25" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 104.37 120.75 L 95.43 121.06 L 98.92 118.25 L 98.77 113.79 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
<g>
<path d="M 177.37 60.26 L 190.38 67.34" fill="none" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
<path d="M 195.65 70.21 L 186.71 69.9 L 190.38 67.34 L 190.53 62.87 Z" fill="#5c5c5c" stroke="#5c5c5c" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(92, 92, 92), rgb(158, 158, 158)); stroke: light-dark(rgb(92, 92, 92), rgb(158, 158, 158));"/>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display
</text>
</a>
</switch>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -3,10 +3,10 @@
The following list gives an overview of the samples provided in subdirectories. The following list gives an overview of the samples provided in subdirectories.
Each sub directory essentially is an individual npm package arranged in an [all-in-one monorepo](#all-in-one-monorepo) umbrella setup. Each sub directory essentially is an individual npm package arranged in an [all-in-one monorepo](#all-in-one-monorepo) umbrella setup.
![](etc/samples.drawio.svg) ![](samples.drawio.svg)
## [@capire/bookshop](bookshop) ## [@capire/bookshop](../bookshop)
- [Getting Started](https://cap.cloud.sap/docs/get-started/in-a-nutshell) with CAP, briefly introducing: - [Getting Started](https://cap.cloud.sap/docs/get-started/in-a-nutshell) with CAP, briefly introducing:
- [Project Setup](https://cap.cloud.sap/docs/get-started/) and [Layouts](https://cap.cloud.sap/docs/get-started/projects) - [Project Setup](https://cap.cloud.sap/docs/get-started/) and [Layouts](https://cap.cloud.sap/docs/get-started/projects)
@@ -17,24 +17,24 @@ Each sub directory essentially is an individual npm package arranged in an [all-
- [Using Databases](https://cap.cloud.sap/docs/guides/databases) - [Using Databases](https://cap.cloud.sap/docs/guides/databases)
## [@capire/common](common) ## [@capire/common](../common)
- Showcases how to extend [@sap/cds/common](https://cap.cloud.sap/docs/cds/common) thereby covering: - Showcases how to extend [@sap/cds/common](https://cap.cloud.sap/docs/cds/common) thereby covering:
- Building [extension packages](https://cap.cloud.sap/docs/guides/domain-models#aspects-extensibility) - Building [extension packages](https://cap.cloud.sap/docs/guides/domain-models#aspects-extensibility)
- Providing [reuse packages](https://cap.cloud.sap/docs/get-started/projects#sharing-and-reusing-content) - Providing [reuse packages](https://cap.cloud.sap/docs/get-started/projects#sharing-and-reusing-content)
- [Verticalization](https://cap.cloud.sap/docs/cds/common#adapting-to-your-needs) - [Verticalization](https://cap.cloud.sap/docs/cds/common#adapting-to-your-needs)
- Using [Aspects](https://cap.cloud.sap/docs/cds/cdl#aspects) - Using [Aspects](https://cap.cloud.sap/docs/cds/cdl#aspects)
- Used in the [fiori app sample](#fiori) - Used in the [bookstore sample](#capire-bookstore)
## [@capire/orders](orders) ## [@capire/orders](../orders)
- A standalone orders management service, demonstrating: - A standalone orders management service, demonstrating:
- Using [Compositions](https://cap.cloud.sap/docs/cds/cdl#compositions) in [Domain Models](https://cap.cloud.sap/docs/guides/domain-models), along with - Using [Compositions](https://cap.cloud.sap/docs/cds/cdl#compositions) in [Domain Models](https://cap.cloud.sap/docs/guides/domain-models), along with
- [Serving deeply nested documents](https://cap.cloud.sap/docs/guides/generic-providers#serving-structured-data) - [Serving deeply nested documents](https://cap.cloud.sap/docs/guides/generic-providers#serving-structured-data)
## [@capire/reviews](reviews) ## [@capire/reviews](../reviews)
- Shows how to implement a modular service to manage product reviews, including: - Shows how to implement a modular service to manage product reviews, including:
- Consuming other services synchronously and asynchronously - Consuming other services synchronously and asynchronously
@@ -47,22 +47,18 @@ Each sub directory essentially is an individual npm package arranged in an [all-
- As well as managed data, input validations, and authorization - As well as managed data, input validations, and authorization
## [@capire/bookstore](bookstore) ## [@capire/bookstore](../bookstore)
- A [composite app, reusing and combining](https://cap.cloud.sap/docs/guides/extensibility/composition) these packages: - A [composite app, reusing and combining](https://cap.cloud.sap/docs/guides/extensibility/composition) these packages:
- [@capire/bookshop](bookshop) - [@capire/bookshop](../bookshop)
- [@capire/reviews](reviews) - [@capire/reviews](../reviews)
- [@capire/orders](orders) - [@capire/orders](../orders)
- [@capire/common](common) - [@capire/common](../common)
- [@capire/data-viewer](etc/data-viewer) - [@capire/data-viewer](data-viewer)
- [The Vue.js app](bookshop/app/vue) imported from `bookshop` is served as well - [The Vue.js app](../bookshop/app/vue) imported from `bookshop` is served as well
- [The Vue.js app](reviews/app/vue) imported from `reviews` is served as well - [The Vue.js app](../reviews/app/vue) imported from `reviews` is served as well
- [The Vue.js app](etc/data-viewer/app/data) imported from `data-viewer` is served as well - [The Vue.js app](data-viewer/app/data) imported from `data-viewer` is served as well
- [The Fiori app](orders/app) imported from `orders` is served as well - [The Fiori app](../orders/app) imported from `orders` is served as well
## [@capire/fiori](fiori)
- Adds an SAP Fiori elements application to bookstore, thereby introducing: - Adds an SAP Fiori elements application to bookstore, thereby introducing:
- OData Annotations in `.cds` files - OData Annotations in `.cds` files
- Support for Fiori Draft - Support for Fiori Draft
@@ -75,4 +71,4 @@ See the [Serving Fiori UIs](https://cap.cloud.sap/docs/advanced/fiori) documenta
# All-in-one Monorepo # All-in-one Monorepo
Each sample sub directory essentially is a standard npm package, some with standard npm dependencies to other samples. The root folder's [package.json](package.json) has local links to the sub folders, such that an `npm install` populates a local `node_modules` folder and acts like a local npm registry to the individual sample packages. Each sample sub directory essentially is a standard npm package, some with standard npm dependencies to other samples. The root folder's [package.json](../package.json) has local links to the sub folders, such that an `npm install` populates a local `node_modules` folder and acts like a local npm registry to the individual sample packages.