Commit 1f9123a0 authored by tiven wang's avatar tiven wang 🤞

odata v4 service

parent 99bc3080
......@@ -12,7 +12,8 @@
"ci-build": "npx tsc",
"ci-package": "npm prune --production && cp -r dist package.json index.html deployment/",
"ci-backend-unit-test": "nyc --extension .ts --report-dir ./s4hana_pipeline/reports/coverage-reports/backend-unit/ --reporter cobertura mocha -r ts-node/register test/unit-tests/*.spec.ts --reporter mocha-junit-reporter --reporter-options mochaFile=./s4hana_pipeline/reports/backend-unit/results.xml",
"ci-integration-test": "nyc --extension .ts --report-dir ./s4hana_pipeline/reports/coverage-reports/backend-integration/ --reporter cobertura mocha -r ts-node/register test/integration-tests/*.spec.ts --reporter mocha-junit-reporter --reporter-options mochaFile=./s4hana_pipeline/reports/backend-integration/results.xml"
"ci-integration-test": "nyc --extension .ts --report-dir ./s4hana_pipeline/reports/coverage-reports/backend-integration/ --reporter cobertura mocha -r ts-node/register test/integration-tests/*.spec.ts --reporter mocha-junit-reporter --reporter-options mochaFile=./s4hana_pipeline/reports/backend-integration/results.xml",
"postinstall": "sh scripts/postinstall.sh"
},
"keywords": [
"SAP",
......@@ -31,6 +32,7 @@
"@sap/xssec": "^2.1.17",
"cfenv": "^1.2.2",
"express": "^4.17.0",
"odata-v4-server": "^0.2.13",
"passport": "^0.4.0"
},
"devDependencies": {
......
set -e
set -x
sed -i.bak 's/protected _flush/public _flush/' node_modules/odata-v4-server/build/lib/processor.d.ts
\ No newline at end of file
export interface BusinessPartner {
_id?: number;
firstName?: string;
lastName?: string;
fullName?: string;
}
const businessPartners = [
{
_id: 1,
firstName: "Tiven",
lastName: "Wang",
fullName: "Tiven Wang"
},
{
_id: 2,
firstName: "Elon",
lastName: "Musk",
fullName: "Elon Musk"
}
] as BusinessPartner[];
var lastId = 2;
export const findBusinessPartners = () =>
new Promise<BusinessPartner[]>(resolve => {
resolve(businessPartners);
});
export const findOneBusinessPartner = (id: number) =>
new Promise<BusinessPartner>((resolve, reject) => {
const bp = businessPartners.find(element => element._id === id);
if (bp === undefined) {
reject();
}
resolve(bp);
});
export const insertBusinessPartner = ({ firstName = '', lastName = '' }: BusinessPartner) =>
new Promise<BusinessPartner>(resolve => {
lastId += 1;
const bp = {
_id: lastId,
firstName,
lastName,
fullName: firstName + " " + lastName
};
businessPartners.push(bp);
resolve(bp);
});
export const updateBusinessPartner = (id: number, { firstName, lastName }: BusinessPartner) =>
new Promise((resolve, reject) => {
const index = businessPartners.findIndex(element => element._id === id);
if (index === -1) {
reject();
return;
}
const prevBP = businessPartners[index];
const bp = {
_id: prevBP._id,
firstName: firstName !== undefined ? firstName : prevBP.firstName,
lastName: lastName !== undefined ? lastName : prevBP.lastName,
fullName: firstName + " " + lastName,
};
businessPartners[index] = bp;
resolve();
});
export const deleteBusinessPartner = (id: number) =>
new Promise((resolve, reject) => {
const index = businessPartners.findIndex(element => element._id === id);
if (index === -1) {
reject();
return;
}
businessPartners.splice(index, 1);
resolve();
});
\ No newline at end of file
import { odata, ODataController } from 'odata-v4-server';
import { deleteBusinessPartner, findOneBusinessPartner, findBusinessPartners, insertBusinessPartner, updateBusinessPartner } from '../../BusinessPartner';
import BusinessPartner from '../models/BusinessPartner';
@odata.type(BusinessPartner)
export default class BusinessPartnersController extends ODataController {
@odata.GET
public async find(): Promise<BusinessPartner[]> {
const bps = await findBusinessPartners();
return bps;
}
@odata.GET
public async findOne(@odata.key id: number): Promise<BusinessPartner> {
const bps = await findOneBusinessPartner(id);
return bps;
}
@odata.POST
public async insert(@odata.body body: any): Promise<BusinessPartner> {
// BUG: CANNOT BE EMPTY OBJECT
const bps = await insertBusinessPartner(body);
return bps;
}
@odata.PATCH
public async update(@odata.key id: number, @odata.body body: any) {
// BUG: CANNOT BE EMPTY OBJECT
await updateBusinessPartner(id, body);
}
@odata.DELETE
public async remove(@odata.key id: number) {
await deleteBusinessPartner(id);
}
}
\ No newline at end of file
import { odata, ODataServer } from 'odata-v4-server';
import BusinessPartnersController from './controllers/BusinessPartnerController';
@odata.namespace('My')
@odata.controller(BusinessPartnersController, true)
export default class MyODataServer extends ODataServer {}
\ No newline at end of file
import { Edm } from 'odata-v4-server';
import { BusinessPartner as IBP } from '../../BusinessPartner'
export default class BusinessPartner implements IBP {
@Edm.Key
@Edm.Int32
/* tslint:disable-next-line */
public _id?: number;
@Edm.String
public firstName?: string;
@Edm.String
public lastName?: string;
@Edm.String
public fullName?: string;
}
\ No newline at end of file
import app from "./application";
const cfenv = require("cfenv");
import MyODataServer from './MyODataServer';
const appEnv = cfenv.getAppEnv();
const port = 8080;
app.use('/odata', MyODataServer.create());
app.listen(appEnv.port || port, appEnv.bind, () => {
console.log("Express server listening on port " + appEnv.url);
});
......
{
"compilerOptions": {
/* Basic Options */
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
......@@ -9,7 +9,7 @@
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "dist" /* Redirect output structure to the directory. */,
"rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
......@@ -44,7 +44,7 @@
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
......@@ -54,8 +54,8 @@
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"exclude": [
"test"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment