Skip to content

Commit efca714

Browse files
authored
Merge pull request #17 from oracle-samples/feature-full-export
Feature: Activity File Proeprties Management
2 parents 0976eb8 + 9db01fd commit efca714

File tree

9 files changed

+641
-241
lines changed

9 files changed

+641
-241
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ In order to use this library you need to have access to an Oracle Field Service
3535

3636
`updateActivity(activityId, activityData)`: Update activity details
3737

38+
`setActivityFileProperty(activityId, propertyId, file)`: Set file property
39+
40+
`getActivityFilePropertyMetadata(activityId, propertyId)`: Get file property metadata
41+
42+
`getActivityFilePropertyContent(activityId, propertyId, contentType)`: Get file property content
43+
44+
`getActivityFileProperty(activityId, propertyId)`: Get file property (content and metadata)
45+
3846
### Core: Subscription Management
3947

4048
`getSubscriptions()`: Get existing subscriptions

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
| `createActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-post.html |
77
| `deleteActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-delete.html |
88
| `getActivityDetails`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-get.html |
9+
| `setFileProperty`|https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-propertylabel-put.html |
10+
| `getFileProperty`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-propertylabel-get.html |
911
| `updateActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-patch.html
1012
| `getSubscriptions` | https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-events-subscriptions-get.html
1113
| `importPlugins` | https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofscmetadata-v1-plugins-custom-actions-import-post.html

package-lock.json

Lines changed: 225 additions & 155 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
],
66
"name": "@ofs-users/proxy",
77
"type": "module",
8-
"version": "1.8.1",
8+
"version": "1.8.3",
99
"description": "A Javascript proxy to access Oracle Field Service via REST API",
1010
"main": "dist/ofs.es.js",
1111
"module": "dist/ofs.es.js",
@@ -46,7 +46,7 @@
4646
}
4747
},
4848
"devDependencies": {
49-
"@babel/preset-typescript": "^7.18.6",
49+
"@babel/preset-typescript": "^7.23.3",
5050
"@faker-js/faker": "^8.3.1",
5151
"@jest/globals": "^29.3.1",
5252
"@rollup/plugin-terser": "^0.2.1",
@@ -65,6 +65,7 @@
6565
"typescript": "^4.9.4"
6666
},
6767
"dependencies": {
68+
"@ofs-users/proxy": "^1.8.2",
6869
"tslib": "^2.4.1"
6970
}
7071
}

src/OFS.ts

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
OFSGetPropertiesParams,
1616
} from "./model";
1717

18+
export * from "./model";
1819
export class OFS {
1920
private _credentials!: OFSCredentials;
2021
private _hash!: string;
@@ -57,7 +58,8 @@ export class OFS {
5758

5859
private _get(
5960
partialURL: string,
60-
params: any = undefined
61+
params: any = undefined,
62+
extraHeaders: Headers = new Headers()
6163
): Promise<OFSResponse> {
6264
var theURL = new URL(partialURL, this._baseURL);
6365
if (params != undefined) {
@@ -66,6 +68,10 @@ export class OFS {
6668
}
6769
var myHeaders = new Headers();
6870
myHeaders.append("Authorization", this.authorization);
71+
extraHeaders.forEach((value, key) => {
72+
console.log(key, value);
73+
myHeaders.append(key, value);
74+
});
6975
var requestOptions = {
7076
method: "GET",
7177
headers: myHeaders,
@@ -74,12 +80,24 @@ export class OFS {
7480
.then(async function (response) {
7581
// Your code for handling the data you get from the API
7682
if (response.status < 400) {
77-
var data = await response.json();
83+
var data;
84+
if (
85+
response.headers.get("Content-Type")?.includes("json")
86+
) {
87+
data = await response.json();
88+
} else if (
89+
response.headers.get("Content-Type")?.includes("text")
90+
) {
91+
data = await response.text();
92+
} else {
93+
data = await response.blob();
94+
}
7895
return new OFSResponse(
7996
theURL,
8097
response.status,
8198
undefined,
82-
data
99+
data,
100+
response.headers.get("Content-Type") || undefined
83101
);
84102
} else {
85103
return new OFSResponse(
@@ -134,27 +152,51 @@ export class OFS {
134152
return fetchPromise;
135153
}
136154

137-
private _put(partialURL: string, requestData: any): Promise<OFSResponse> {
155+
private _put(
156+
partialURL: string,
157+
requestData: any,
158+
contentType: string = "application/json",
159+
fileName?: string
160+
): Promise<OFSResponse> {
138161
var theURL = new URL(partialURL, this._baseURL);
139162
var myHeaders = new Headers();
140163
myHeaders.append("Authorization", this.authorization);
141-
myHeaders.append("Content-Type", "application/json");
164+
myHeaders.append("Content-Type", contentType);
165+
if (contentType == "application/json") {
166+
requestData = JSON.stringify(requestData);
167+
}
168+
if (fileName) {
169+
myHeaders.append(
170+
"Content-Disposition",
171+
`attachment; filename=${fileName}`
172+
);
173+
}
142174
var requestOptions: RequestInit = {
143175
method: "PUT",
144176
headers: myHeaders,
145-
body: JSON.stringify(requestData),
177+
body: requestData,
146178
};
147179
const fetchPromise = fetch(theURL, requestOptions)
148180
.then(async function (response) {
149181
// Your code for handling the data you get from the API
150182
if (response.status < 400) {
151-
var data = await response.json();
152-
return new OFSResponse(
153-
theURL,
154-
response.status,
155-
undefined,
156-
data
157-
);
183+
if (response.status == 204) {
184+
//No data here
185+
return new OFSResponse(
186+
theURL,
187+
response.status,
188+
undefined,
189+
undefined
190+
);
191+
} else {
192+
var data = await response.json();
193+
return new OFSResponse(
194+
theURL,
195+
response.status,
196+
undefined,
197+
data
198+
);
199+
}
158200
} else {
159201
return new OFSResponse(
160202
theURL,
@@ -319,6 +361,69 @@ export class OFS {
319361
return this._patch(partialURL, data);
320362
}
321363

364+
async getActivityFilePropertyContent(
365+
aid: number,
366+
propertyLabel: string,
367+
nediaType: string = "*/*"
368+
): Promise<OFSResponse> {
369+
var myHeaders = new Headers();
370+
myHeaders.append("Accept", nediaType);
371+
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
372+
return this._get(partialURL, undefined, myHeaders);
373+
}
374+
375+
async getActivityFilePropertyMetadata(
376+
aid: number,
377+
propertyLabel: string
378+
): Promise<OFSResponse> {
379+
var myHeaders = new Headers();
380+
myHeaders.append("Accept", "*/*");
381+
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
382+
return this._get(partialURL, undefined, myHeaders);
383+
}
384+
385+
async getActivityFileProperty(
386+
aid: number,
387+
propertyLabel: string
388+
): Promise<OFSResponse> {
389+
var myHeaders = new Headers();
390+
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
391+
var metadata = await this.getActivityFilePropertyMetadata(
392+
aid,
393+
propertyLabel
394+
);
395+
if (metadata.status < 400) {
396+
var contentType = metadata.contentType;
397+
if (contentType) {
398+
myHeaders.append("Accept", contentType);
399+
}
400+
var content = this._get(partialURL, undefined, myHeaders);
401+
return new OFSResponse(
402+
metadata.url,
403+
metadata.status,
404+
metadata.description,
405+
{
406+
...metadata.data,
407+
content: (await content).data,
408+
},
409+
metadata.contentType
410+
);
411+
} else {
412+
return metadata;
413+
}
414+
}
415+
416+
async setActivityFileProperty(
417+
aid: number,
418+
propertyLabel: string,
419+
blob: Blob,
420+
fileName: string,
421+
contentType: string = "*/*"
422+
): Promise<OFSResponse> {
423+
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
424+
return this._put(partialURL, blob, contentType, fileName);
425+
}
426+
322427
// Core: User Management
323428
async getUsers(
324429
offset: number = 0,

src/model.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,28 @@ export interface OFSResponseInterface {
1616
description: string | undefined;
1717
data: any;
1818
url: URL;
19+
contentType?: string;
1920
}
2021

2122
export class OFSResponse implements OFSResponseInterface {
2223
status: number = -1;
2324
description: string | undefined;
2425
data: any;
2526
url: URL;
27+
contentType?: string;
2628

27-
constructor(url: URL, status: number, description?: string, data?: any) {
29+
constructor(
30+
url: URL,
31+
status: number,
32+
description?: string,
33+
data?: any,
34+
contentType?: string
35+
) {
2836
this.status = status;
2937
this.description = description;
3038
this.data = data;
3139
this.url = url;
40+
this.contentType = contentType;
3241
}
3342
}
3443

test/general/base.test.ts

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -31,76 +31,6 @@ test("Get Subscriptions", async () => {
3131
expect(myProxy.instance).toBe(myCredentials.instance);
3232
});
3333

34-
test("Get Activity Details", async () => {
35-
var aid = 3954799;
36-
var result = await myProxy.getActivityDetails(aid);
37-
expect(result.data.activityId).toBe(aid);
38-
});
39-
40-
test("Get non valid Activity Details", async () => {
41-
var aid = -1;
42-
var result = await myProxy.getActivityDetails(aid);
43-
expect(result.status).toBe(400);
44-
});
45-
46-
test("Create Activity", async () => {
47-
var activityData = {
48-
activityType: "01",
49-
resourceId: "FLUSA",
50-
};
51-
var result = await myProxy.createActivity(activityData);
52-
expect(result.status).toBe(201);
53-
expect(result.data.activityType).toBe(activityData.activityType);
54-
// For cleanup
55-
var activityId = result.data.activityId;
56-
activityList.push(activityId);
57-
});
58-
59-
test("Delete Activity", async () => {
60-
var activityData = {
61-
activityType: "01",
62-
resourceId: "FLUSA",
63-
};
64-
var result = await myProxy.createActivity(activityData);
65-
expect(result.status).toBe(201);
66-
expect(result.data.activityType).toBe(activityData.activityType);
67-
var activityId = result.data.activityId;
68-
activityList.push(activityId);
69-
var result = await myProxy.deleteActivity(activityId);
70-
expect(result.status).toBe(204);
71-
});
72-
73-
test("Update Activity Details", async () => {
74-
var activityData = {
75-
activityType: "01",
76-
resourceId: "FLUSA",
77-
};
78-
var result = await myProxy.createActivity(activityData);
79-
expect(result.status).toBe(201);
80-
var aid = result.data.activityId;
81-
var initialName = "Gizella Quintero";
82-
var data = {
83-
customerName: "NewName",
84-
};
85-
var result = await myProxy.updateActivity(aid, data);
86-
expect(result.data.activityId).toBe(aid);
87-
expect(result.data.customerName).toBe(data.customerName);
88-
expect((await myProxy.getActivityDetails(aid)).data.customerName).toBe(
89-
data.customerName
90-
);
91-
expect(
92-
(await myProxy.updateActivity(aid, { customerName: initialName })).data
93-
.customerName
94-
).toBe(initialName);
95-
activityList.push(aid);
96-
});
97-
98-
test("Update non valid Activity Details", async () => {
99-
var aid = -1;
100-
var result = await myProxy.updateActivity(aid, {});
101-
expect(result.status).toBe(404);
102-
});
103-
10434
test("Update Plugin (path)", async () => {
10535
var result = await myProxy.importPlugins("test/test_plugin.xml");
10636
try {

0 commit comments

Comments
 (0)