From 2ca9fc66648ee43100c3046b4d41b07bdbb14964 Mon Sep 17 00:00:00 2001 From: Albin Ramovic Date: Fri, 25 Oct 2024 09:13:05 +0200 Subject: [PATCH 1/3] add custom index page to the ord-sample --- xmpl/app/index.css | 132 ++++++++++++++++++++++++++++++++++++++++++++ xmpl/app/index.html | 119 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 xmpl/app/index.css create mode 100644 xmpl/app/index.html diff --git a/xmpl/app/index.css b/xmpl/app/index.css new file mode 100644 index 0000000..a8c5daa --- /dev/null +++ b/xmpl/app/index.css @@ -0,0 +1,132 @@ +body { + font-family: Avenir Next, sans-serif; + background: #f8fbff; + } + + body #welcome { + margin: 30px auto 50px; + padding: 0 30px; + max-width: 900px; + } + + body #welcome h1, #welcome h3, #welcome h2, #welcome p { + margin: 20px 0; + color: #47637d; + font-weight: 400; + } + + body #welcome h3.header { + margin: 20px 0 0 0; + background-color: #537492; + color: white; + } + + body #welcome h3 a { + color: inherit; + font-weight: 500; + } + + body #welcome h3 a span { + padding: 5px 15px; + font-weight: 300; + transition: all 0.2s ease-in; + } + + body #welcome h3 a:first-child span { + display: inline-block; + padding: 5px 15px; + } + + body #welcome h3 a span:hover { + color: #92b2d0; + } + + body #welcome ul { + margin: 0; + background: #91adc5; + list-style-type: none; + padding-inline-start: 20px; + } + + body #welcome li { + display: inline-grid; + grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); + width: 100%; + margin-bottom: 1px; + background-color: #d0e9ff; + padding: 0; + /* + -moz-transition: background color 0.2s ease-in; + -webkit-transition: background 0.2s ease-in; + -o-transition: background 0.2s ease-in; + /* Standard */ + transition: all 0.1s ease-in; + } + + body #welcome ul li div:not(:first-child) a { + font-weight: 300; + } + + body #welcome a { + text-decoration: none; + } + + body #welcome li a, body #welcome li > span { + padding: 4px 10px; + font-weight: 500; + color: #1d5985; + transition: all 0.1s ease-in; + } + body #welcome li.operation span { + font-style: italic; + } + + body #welcome li a span:hover { + color: #f0faff; + background-color: #a7c8e1; + } + + body #welcome .preview { + font-size: small; + } + + footer { + border-top: .5px solid; + margin-top: 44px; + padding-top: 22px; + width: 400px; + font-size: 90%; + } + + @media (prefers-color-scheme: dark) { + body { background: #0a2138; } + + body #welcome h1, #welcome h3, #welcome h2, #welcome p { + color: #a6c1d9; + } + body #welcome h3 a { + color: #e2efff; + } + body #welcome ul { + background: #7894ad; + } + body #welcome li { + background-color: #506d88; + } + body #welcome li a, body #welcome li:hover div:not(:first-child) a, body #welcome li > span { + color: #d0e4f2; + } + body #welcome li a:hover { + color: white; + background-color: #7894ad; + } + + body #welcome h3.header { + background-color: #304c65; + } + + footer { + border-top: .5px solid #456; + color: #567; + } + } \ No newline at end of file diff --git a/xmpl/app/index.html b/xmpl/app/index.html new file mode 100644 index 0000000..508ec54 --- /dev/null +++ b/xmpl/app/index.html @@ -0,0 +1,119 @@ + + + + + @capire/ord-sample 1.0.0 + + + + +
+

Welcome to the @capire/ord-sample 1.0.0

+

Serving @capire/ord-sample 1.0.0

+ +

These are the paths currently served:

+ +

Web Applications:

+ + +

Service Endpoints:

+ +
+

+ /odata/v4/local/ $metadata +

+
    +
+
    +
+
+ +
+

+ /odata/v4/processor/ $metadata +

+ +
    +
+
+ +
+

+ /odata/v4/admin/ $metadata +

+ +
    +
+
+ + + +
+ + + From 05ec03dee0d5ed2e8ef0c52da395f63dd3ee5f1c Mon Sep 17 00:00:00 2001 From: Albin Ramovic Date: Mon, 24 Feb 2025 16:29:05 +0100 Subject: [PATCH 2/3] initial commit --- xmpl/app/index.css | 132 --------------------------------------- xmpl/app/index.html | 119 ----------------------------------- xmpl/package.json | 32 ++++++---- xmpl/srv/ord-service.cds | 12 ++++ xmpl/srv/ord-service.mjs | 73 ++++++++++++++++++++++ 5 files changed, 105 insertions(+), 263 deletions(-) delete mode 100644 xmpl/app/index.css delete mode 100644 xmpl/app/index.html create mode 100644 xmpl/srv/ord-service.cds create mode 100644 xmpl/srv/ord-service.mjs diff --git a/xmpl/app/index.css b/xmpl/app/index.css deleted file mode 100644 index a8c5daa..0000000 --- a/xmpl/app/index.css +++ /dev/null @@ -1,132 +0,0 @@ -body { - font-family: Avenir Next, sans-serif; - background: #f8fbff; - } - - body #welcome { - margin: 30px auto 50px; - padding: 0 30px; - max-width: 900px; - } - - body #welcome h1, #welcome h3, #welcome h2, #welcome p { - margin: 20px 0; - color: #47637d; - font-weight: 400; - } - - body #welcome h3.header { - margin: 20px 0 0 0; - background-color: #537492; - color: white; - } - - body #welcome h3 a { - color: inherit; - font-weight: 500; - } - - body #welcome h3 a span { - padding: 5px 15px; - font-weight: 300; - transition: all 0.2s ease-in; - } - - body #welcome h3 a:first-child span { - display: inline-block; - padding: 5px 15px; - } - - body #welcome h3 a span:hover { - color: #92b2d0; - } - - body #welcome ul { - margin: 0; - background: #91adc5; - list-style-type: none; - padding-inline-start: 20px; - } - - body #welcome li { - display: inline-grid; - grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); - width: 100%; - margin-bottom: 1px; - background-color: #d0e9ff; - padding: 0; - /* - -moz-transition: background color 0.2s ease-in; - -webkit-transition: background 0.2s ease-in; - -o-transition: background 0.2s ease-in; - /* Standard */ - transition: all 0.1s ease-in; - } - - body #welcome ul li div:not(:first-child) a { - font-weight: 300; - } - - body #welcome a { - text-decoration: none; - } - - body #welcome li a, body #welcome li > span { - padding: 4px 10px; - font-weight: 500; - color: #1d5985; - transition: all 0.1s ease-in; - } - body #welcome li.operation span { - font-style: italic; - } - - body #welcome li a span:hover { - color: #f0faff; - background-color: #a7c8e1; - } - - body #welcome .preview { - font-size: small; - } - - footer { - border-top: .5px solid; - margin-top: 44px; - padding-top: 22px; - width: 400px; - font-size: 90%; - } - - @media (prefers-color-scheme: dark) { - body { background: #0a2138; } - - body #welcome h1, #welcome h3, #welcome h2, #welcome p { - color: #a6c1d9; - } - body #welcome h3 a { - color: #e2efff; - } - body #welcome ul { - background: #7894ad; - } - body #welcome li { - background-color: #506d88; - } - body #welcome li a, body #welcome li:hover div:not(:first-child) a, body #welcome li > span { - color: #d0e4f2; - } - body #welcome li a:hover { - color: white; - background-color: #7894ad; - } - - body #welcome h3.header { - background-color: #304c65; - } - - footer { - border-top: .5px solid #456; - color: #567; - } - } \ No newline at end of file diff --git a/xmpl/app/index.html b/xmpl/app/index.html deleted file mode 100644 index 508ec54..0000000 --- a/xmpl/app/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - @capire/ord-sample 1.0.0 - - - - -
-

Welcome to the @capire/ord-sample 1.0.0

-

Serving @capire/ord-sample 1.0.0

- -

These are the paths currently served:

- -

Web Applications:

-
    - — none — -
- -

Service Endpoints:

- -
-

- /odata/v4/local/ $metadata -

-
    -
-
    -
-
- -
-

- /odata/v4/processor/ $metadata -

- -
    -
-
- -
-

- /odata/v4/admin/ $metadata -

- -
    -
-
- - - -
- - - diff --git a/xmpl/package.json b/xmpl/package.json index b79f885..805eb19 100644 --- a/xmpl/package.json +++ b/xmpl/package.json @@ -1,14 +1,22 @@ { - "name": "@capire/ord-sample", - "description": "this is a xmpl application description", - "version": "1.0.0", - "dependencies": { - "@cap-js/ord": "*", - "@capire/incidents": "*", - "@sap/cds": "*" - }, - "devDependencies": { - "@cap-js/sqlite": "*" - }, - "private": true + "name": "@capire/ord-sample", + "description": "this is a xmpl application description", + "version": "1.0.0", + "dependencies": { + "@cap-js/ord": "*", + "@capire/incidents": "*", + "@sap/cds": "*" + }, + "devDependencies": { + "@cap-js/sqlite": "*" + }, + "private": true, + "cds": { + "requires": { + "SAP ORD Service": { + "model": "@cap-js/ord/srv/ord-service", + "service": "OrdService" + } + } + } } diff --git a/xmpl/srv/ord-service.cds b/xmpl/srv/ord-service.cds new file mode 100644 index 0000000..c464d1d --- /dev/null +++ b/xmpl/srv/ord-service.cds @@ -0,0 +1,12 @@ +// @requires: 'ORDconsumer' +@rest @path:'/ord/v1' +service OrdService { + @readonly entity documents { + key id: String; + } + @readonly entity csn { + key id: String; + } + + function api (service: String, format: String) returns {}; +} \ No newline at end of file diff --git a/xmpl/srv/ord-service.mjs b/xmpl/srv/ord-service.mjs new file mode 100644 index 0000000..30b7976 --- /dev/null +++ b/xmpl/srv/ord-service.mjs @@ -0,0 +1,73 @@ +import cds from '@sap/cds' +export class OrdService extends cds.ApplicationService { + init(){ + + this.on('READ','documents', req => { + let csn = cds.context?.model || cds.model + return { ord: csn } + }) + + /** + * Just an example to do something with id, if given. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/documents + * - http://localhost:4004/ord/v1/documents/CatalogService + * - http://localhost:4004/ord/v1/documents/CatalogService.Books + * - http://localhost:4004/ord/v1/documents/CatalogService.Authors + */ + this.on('READ','csn', req => { + let csn = cds.context?.model || cds.model + let { id } = req.data + if (id) csn = csn.definitions[id] || 'not in model!' + return { id, csn } + }) + + /** + * Just an example to serve arbitrary content with a function. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/api?service=CatalogService + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=edmx + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=edmx-v2 + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=openapi + */ + this.on('api', req => { + let csn = cds.context?.model || cds.model + let { service, format = 'csn' } = req.data + let { res } = req.http + if (format === 'csn') { + if (!service) return res.send(csn) + service = csn.services[service] + return res.send({ definitions: [ service, ...service.entities ] .reduce ((all,e) => { + let d = all[e.name] = {...e} + delete d.projection // not part of the API + delete d.query // not part of the API + return all + },{})}) + } + let api = cds.compile(csn).to[format]({service}) + return res.send(api) + }) + + /** + * Example how to register arbitrary express routes, + * and map them to our service's interface. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/csn/CatalogService + * - http://localhost:4004/ord/v1/edmx/CatalogService + * - http://localhost:4004/ord/v1/openapi/CatalogService + * - http://localhost:4004/ord/v1/asyncapi/CatalogService + * + * NOTE: we add cds.middlewares.before to the route, which gives us all + * the context and auth handling, which is also available to CAP services. + */ + cds.app.get (`${this.path}/:api?/:service?`, cds.middlewares.before, req => { + const { api, service } = req.params + return this.api (service, api) + }) + + return super.init() + } +} \ No newline at end of file From 9d946d01af8a7fde1632b3bbd8f43991e53808cc Mon Sep 17 00:00:00 2001 From: Albin Ramovic Date: Tue, 25 Feb 2025 11:07:24 +0100 Subject: [PATCH 3/3] tmp change - add TODO --- xmpl/srv/ord-service.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xmpl/srv/ord-service.mjs b/xmpl/srv/ord-service.mjs index 30b7976..644cb3c 100644 --- a/xmpl/srv/ord-service.mjs +++ b/xmpl/srv/ord-service.mjs @@ -62,6 +62,11 @@ export class OrdService extends cds.ApplicationService { * * NOTE: we add cds.middlewares.before to the route, which gives us all * the context and auth handling, which is also available to CAP services. + * + * TODO: Paths should be the following: + * - http://localhost:4004/ord/v1/documents/ord-document + * - http://localhost:4004/ord/v1/:ordId/:fileName + * - http://localhost:4004/.well-known/open-resource-discovery */ cds.app.get (`${this.path}/:api?/:service?`, cds.middlewares.before, req => { const { api, service } = req.params