ofsc-utility 1.0.47 → 1.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/resources/index.d.ts +1 -0
- package/dist/resources/index.js +9 -0
- package/dist/users/index.d.ts +4 -0
- package/dist/users/index.js +21 -1
- package/dist/utilities/index.d.ts +8 -0
- package/dist/utilities/index.js +133 -1
- package/package.json +1 -1
- package/readme.md +378 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
10
10
|
- version 1.0.46
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
|
+
- add user management methods for standalone OFSC
|
|
14
|
+
- Update version and add resource management APIs
|
|
15
|
+
- version 1.0.47 and add resource APIs
|
|
13
16
|
- release v1.0.44 with getResource function and updated keywords
|
|
14
17
|
- version 1.0.43 with built-in resilience and exponential backoff
|
|
15
18
|
- Add -c flag to skip CHANGELOG updates and auto-update logic
|
|
@@ -6,3 +6,4 @@ export declare function getworkSkillsOfResource(clientId: string, clientSecret:
|
|
|
6
6
|
data: any;
|
|
7
7
|
}>;
|
|
8
8
|
export declare function getResourcebyId(resourceId: string, clientId: string, clientSecret: string, instanceUrl: string, initialToken?: string): Promise<ResourceResponse>;
|
|
9
|
+
export declare function updateResourcebyId(resourceId: string, clientId: string, clientSecret: string, instanceUrl: string, initialToken: string | undefined, payload: {}): Promise<ResourceResponse>;
|
package/dist/resources/index.js
CHANGED
|
@@ -40,6 +40,7 @@ exports.downloadAllResourcesCSV = downloadAllResourcesCSV;
|
|
|
40
40
|
exports.AllResources = AllResources;
|
|
41
41
|
exports.getworkSkillsOfResource = getworkSkillsOfResource;
|
|
42
42
|
exports.getResourcebyId = getResourcebyId;
|
|
43
|
+
exports.updateResourcebyId = updateResourcebyId;
|
|
43
44
|
const fs = __importStar(require("fs"));
|
|
44
45
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
45
46
|
const index_1 = require("../oauthTokenService/index");
|
|
@@ -149,3 +150,11 @@ async function getResourcebyId(resourceId, clientId, clientSecret, instanceUrl,
|
|
|
149
150
|
};
|
|
150
151
|
return fetchResources(0, initialToken);
|
|
151
152
|
}
|
|
153
|
+
async function updateResourcebyId(resourceId, clientId, clientSecret, instanceUrl, initialToken = "", payload) {
|
|
154
|
+
const fetchResources = async (offset, token) => {
|
|
155
|
+
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/resources/${encodeURIComponent(resourceId)}`;
|
|
156
|
+
const res = await (0, utilities_1.fetchPatchWithRetry)(url, clientId, clientSecret, instanceUrl, token, payload);
|
|
157
|
+
return res.data;
|
|
158
|
+
};
|
|
159
|
+
return fetchResources(0, initialToken);
|
|
160
|
+
}
|
package/dist/users/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ResourceResponse } from "../types";
|
|
1
2
|
export declare function downloadAllUsersCSV(clientId: string, clientSecret: string, instanceUrl: string): Promise<void>;
|
|
2
3
|
export { generateUsersCollaborationCSV } from './collaborationGroups';
|
|
3
4
|
declare const OfscUserUtility: {
|
|
@@ -5,7 +6,10 @@ declare const OfscUserUtility: {
|
|
|
5
6
|
downloadAllUsersCSV: typeof downloadAllUsersCSV;
|
|
6
7
|
downloadAllInactiveUsersCSV: typeof downloadAllInactiveUsersCSV;
|
|
7
8
|
downloadAllInactiveUsers: typeof downloadAllInactiveUsers;
|
|
9
|
+
getUserByLogin: typeof getUserByLogin;
|
|
8
10
|
};
|
|
9
11
|
export declare function downloadAllInactiveUsersCSV(clientId: string, clientSecret: string, instanceUrl: string, inactivityThresholdDays?: number): Promise<void>;
|
|
10
12
|
export declare function downloadAllInactiveUsers(clientId: string, clientSecret: string, instanceUrl: string, inactivityThresholdDays?: number): Promise<Record<string, any>[]>;
|
|
13
|
+
export declare function getUserByLogin(login: string, clientId: string, clientSecret: string, instanceUrl: string, initialToken?: string): Promise<any>;
|
|
14
|
+
export declare function updateUserbyLogin(login: string, clientId: string, clientSecret: string, instanceUrl: string, initialToken: string | undefined, payload: {}): Promise<ResourceResponse>;
|
|
11
15
|
export default OfscUserUtility;
|
package/dist/users/index.js
CHANGED
|
@@ -40,6 +40,8 @@ exports.generateUsersCollaborationCSV = void 0;
|
|
|
40
40
|
exports.downloadAllUsersCSV = downloadAllUsersCSV;
|
|
41
41
|
exports.downloadAllInactiveUsersCSV = downloadAllInactiveUsersCSV;
|
|
42
42
|
exports.downloadAllInactiveUsers = downloadAllInactiveUsers;
|
|
43
|
+
exports.getUserByLogin = getUserByLogin;
|
|
44
|
+
exports.updateUserbyLogin = updateUserbyLogin;
|
|
43
45
|
const fs = __importStar(require("fs"));
|
|
44
46
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
45
47
|
const index_1 = require("../oauthTokenService/index");
|
|
@@ -123,7 +125,8 @@ const OfscUserUtility = {
|
|
|
123
125
|
generateUsersCollaborationCSV: require('./collaborationGroups').generateUsersCollaborationCSV,
|
|
124
126
|
downloadAllUsersCSV,
|
|
125
127
|
downloadAllInactiveUsersCSV,
|
|
126
|
-
downloadAllInactiveUsers
|
|
128
|
+
downloadAllInactiveUsers,
|
|
129
|
+
getUserByLogin
|
|
127
130
|
};
|
|
128
131
|
/**
|
|
129
132
|
* Returns true if the user is "inactive":
|
|
@@ -292,4 +295,21 @@ async function downloadAllInactiveUsers(clientId, clientSecret, instanceUrl, ina
|
|
|
292
295
|
console.log("-------------------------------------");
|
|
293
296
|
return result;
|
|
294
297
|
}
|
|
298
|
+
// /rest/ofscCore/v1/users/{login}
|
|
299
|
+
async function getUserByLogin(login, clientId, clientSecret, instanceUrl, initialToken = "") {
|
|
300
|
+
const fetchUser = async (offset, token) => {
|
|
301
|
+
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/users/${encodeURIComponent(login)}?offset=${offset}&limit=100`;
|
|
302
|
+
const res = await (0, index_2.fetchWithRetry)(url, clientId, clientSecret, instanceUrl, token);
|
|
303
|
+
return res.data;
|
|
304
|
+
};
|
|
305
|
+
return fetchUser(0, initialToken);
|
|
306
|
+
}
|
|
307
|
+
async function updateUserbyLogin(login, clientId, clientSecret, instanceUrl, initialToken = "", payload) {
|
|
308
|
+
const fetchUser = async (offset, token) => {
|
|
309
|
+
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/users/${encodeURIComponent(login)}`;
|
|
310
|
+
const res = await (0, index_2.fetchPatchWithRetry)(url, clientId, clientSecret, instanceUrl, token, payload);
|
|
311
|
+
return res.data;
|
|
312
|
+
};
|
|
313
|
+
return fetchUser(0, initialToken);
|
|
314
|
+
}
|
|
295
315
|
exports.default = OfscUserUtility;
|
|
@@ -13,6 +13,14 @@ export declare const fetchWithRetry: (url: string, clientId: string, clientSecre
|
|
|
13
13
|
data: any;
|
|
14
14
|
token: string;
|
|
15
15
|
}>;
|
|
16
|
+
export declare const fetchPatchWithRetry: (url: string, clientId: string, clientSecret: string, instanceUrl: string, token: string, body: any, retries?: number, baseDelay?: number) => Promise<{
|
|
17
|
+
data: any;
|
|
18
|
+
token: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const fetchPostWithRetry: (url: string, clientId: string, clientSecret: string, instanceUrl: string, token: string, body: any, retries?: number, baseDelay?: number) => Promise<{
|
|
21
|
+
data: any;
|
|
22
|
+
token: string;
|
|
23
|
+
}>;
|
|
16
24
|
export declare function saveCsv<T extends Record<string, any>>(rows: T[], filePath: string): void;
|
|
17
25
|
export declare function xmlNodeToObjects(xmlString: string, parentNodeName: string): Record<string, string>[];
|
|
18
26
|
type SheetRow = Record<string, unknown>;
|
package/dist/utilities/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.fetchWithRetry = void 0;
|
|
39
|
+
exports.fetchPostWithRetry = exports.fetchPatchWithRetry = exports.fetchWithRetry = void 0;
|
|
40
40
|
exports.saveCsv = saveCsv;
|
|
41
41
|
exports.xmlNodeToObjects = xmlNodeToObjects;
|
|
42
42
|
exports.createExcelFile = createExcelFile;
|
|
@@ -122,6 +122,138 @@ const fetchWithRetry = async (url, clientId, clientSecret, instanceUrl, token, r
|
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
exports.fetchWithRetry = fetchWithRetry;
|
|
125
|
+
const fetchPatchWithRetry = async (url, clientId, clientSecret, instanceUrl, token, body, retries = 5, baseDelay = 500) => {
|
|
126
|
+
const doFetch = async (bearer) => {
|
|
127
|
+
return fetch(url, {
|
|
128
|
+
method: "PATCH",
|
|
129
|
+
headers: {
|
|
130
|
+
Authorization: `Bearer ${bearer}`,
|
|
131
|
+
Accept: "application/json",
|
|
132
|
+
"Content-Type": "application/json"
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify(body)
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
console.log(`Patching ${url}`);
|
|
138
|
+
let currentToken = token;
|
|
139
|
+
let tokenRefreshed = false;
|
|
140
|
+
let remainingRetries = retries;
|
|
141
|
+
let delay = baseDelay;
|
|
142
|
+
while (true) {
|
|
143
|
+
let res = await doFetch(currentToken);
|
|
144
|
+
if (res.status === 401 && !tokenRefreshed) {
|
|
145
|
+
console.warn("Token expired — renewing token…");
|
|
146
|
+
currentToken = await (0, oauthTokenService_1.getOAuthToken)(clientId, clientSecret, instanceUrl);
|
|
147
|
+
tokenRefreshed = true;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const responseText = await res.text();
|
|
151
|
+
const isNoRouteToHost = res.status === 400 &&
|
|
152
|
+
responseText.includes("NoRouteToHostException");
|
|
153
|
+
const isRetryableStatus = res.status === 400 ||
|
|
154
|
+
res.status === 429 ||
|
|
155
|
+
res.status === 502 ||
|
|
156
|
+
res.status === 503 ||
|
|
157
|
+
res.status === 504;
|
|
158
|
+
if ((isRetryableStatus || isNoRouteToHost) &&
|
|
159
|
+
remainingRetries > 0) {
|
|
160
|
+
const retryAfter = res.headers.get("Retry-After");
|
|
161
|
+
let retryDelay = delay;
|
|
162
|
+
if (retryAfter) {
|
|
163
|
+
const retryAfterSeconds = Number(retryAfter);
|
|
164
|
+
if (!Number.isNaN(retryAfterSeconds)) {
|
|
165
|
+
retryDelay = retryAfterSeconds * 1000;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
console.warn(`Retrying in ${retryDelay}ms... (${remainingRetries} retries left)`);
|
|
169
|
+
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
170
|
+
remainingRetries--;
|
|
171
|
+
delay *= 2;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (!res.ok) {
|
|
175
|
+
throw new Error(`Request failed: ${res.status} ${res.statusText}\n${responseText}`);
|
|
176
|
+
}
|
|
177
|
+
let data;
|
|
178
|
+
try {
|
|
179
|
+
data = JSON.parse(responseText);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
throw new Error(`Invalid JSON response from ${url}\n${responseText}`);
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
data,
|
|
186
|
+
token: currentToken
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
exports.fetchPatchWithRetry = fetchPatchWithRetry;
|
|
191
|
+
const fetchPostWithRetry = async (url, clientId, clientSecret, instanceUrl, token, body, retries = 5, baseDelay = 500) => {
|
|
192
|
+
const doFetch = async (bearer) => {
|
|
193
|
+
return fetch(url, {
|
|
194
|
+
method: "POST",
|
|
195
|
+
headers: {
|
|
196
|
+
Authorization: `Bearer ${bearer}`,
|
|
197
|
+
Accept: "application/json",
|
|
198
|
+
"Content-Type": "application/json"
|
|
199
|
+
},
|
|
200
|
+
body: JSON.stringify(body)
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
console.log(`Posting ${url}`);
|
|
204
|
+
let currentToken = token;
|
|
205
|
+
let tokenRefreshed = false;
|
|
206
|
+
let remainingRetries = retries;
|
|
207
|
+
let delay = baseDelay;
|
|
208
|
+
while (true) {
|
|
209
|
+
let res = await doFetch(currentToken);
|
|
210
|
+
if (res.status === 401 && !tokenRefreshed) {
|
|
211
|
+
console.warn("Token expired — renewing token…");
|
|
212
|
+
currentToken = await (0, oauthTokenService_1.getOAuthToken)(clientId, clientSecret, instanceUrl);
|
|
213
|
+
tokenRefreshed = true;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const responseText = await res.text();
|
|
217
|
+
const isNoRouteToHost = res.status === 400 &&
|
|
218
|
+
responseText.includes("NoRouteToHostException");
|
|
219
|
+
const isRetryableStatus = res.status === 400 ||
|
|
220
|
+
res.status === 429 ||
|
|
221
|
+
res.status === 502 ||
|
|
222
|
+
res.status === 503 ||
|
|
223
|
+
res.status === 504;
|
|
224
|
+
if ((isRetryableStatus || isNoRouteToHost) &&
|
|
225
|
+
remainingRetries > 0) {
|
|
226
|
+
const retryAfter = res.headers.get("Retry-After");
|
|
227
|
+
let retryDelay = delay;
|
|
228
|
+
if (retryAfter) {
|
|
229
|
+
const retryAfterSeconds = Number(retryAfter);
|
|
230
|
+
if (!Number.isNaN(retryAfterSeconds)) {
|
|
231
|
+
retryDelay = retryAfterSeconds * 1000;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
console.warn(`Retrying in ${retryDelay}ms... (${remainingRetries} retries left)`);
|
|
235
|
+
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
236
|
+
remainingRetries--;
|
|
237
|
+
delay *= 2;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (!res.ok) {
|
|
241
|
+
throw new Error(`Request failed: ${res.status} ${res.statusText}\n${responseText}`);
|
|
242
|
+
}
|
|
243
|
+
let data;
|
|
244
|
+
try {
|
|
245
|
+
data = JSON.parse(responseText);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
throw new Error(`Invalid JSON response from ${url}\n${responseText}`);
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
data,
|
|
252
|
+
token: currentToken
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
exports.fetchPostWithRetry = fetchPostWithRetry;
|
|
125
257
|
const fs_1 = __importDefault(require("fs"));
|
|
126
258
|
const path_1 = __importDefault(require("path"));
|
|
127
259
|
function saveCsv(rows, filePath) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofsc-utility",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.49",
|
|
4
4
|
"description": "TypeScript helpers for Oracle Field Service Cloud (OFSC): events, resources, inventories, metadata and CSV/Excel utilities.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/readme.md
CHANGED
|
@@ -8,6 +8,11 @@ This package exposes grouped API helpers for common OFSC operations, including:
|
|
|
8
8
|
- export/download helpers
|
|
9
9
|
- inventory and activity records
|
|
10
10
|
- metadata file generation
|
|
11
|
+
- user and resource operations for standalone OFSC environments
|
|
12
|
+
|
|
13
|
+
> Note: User and resource-related methods are applicable exclusively to standalone OFSC environments and are not supported in Fusion OFSC.
|
|
14
|
+
|
|
15
|
+
This library is intended for OFSC integrations where the standard OFSC REST APIs are available. The user and resource-related methods are designed for standalone OFSC deployments and should not be relied on for Fusion OFSC environments, where the underlying APIs and behavior can differ.
|
|
11
16
|
|
|
12
17
|
### Built-in resilience for OFSC's server errors
|
|
13
18
|
|
|
@@ -172,6 +177,210 @@ await ofs.downloadAllInactiveUsersCSV(
|
|
|
172
177
|
);
|
|
173
178
|
```
|
|
174
179
|
|
|
180
|
+
### Resource APIs
|
|
181
|
+
|
|
182
|
+
The resource helpers let you export, paginate, inspect, and update OFSC resources.
|
|
183
|
+
|
|
184
|
+
#### `downloadAllResourcesCSV`
|
|
185
|
+
|
|
186
|
+
Exports every resource in the OFSC resource collection to a local `./resources.csv` file.
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
await ofs.downloadAllResourcesCSV(
|
|
190
|
+
process.env.CLIENT_ID,
|
|
191
|
+
process.env.CLIENT_SECRET,
|
|
192
|
+
process.env.INSTANCE_NAME,
|
|
193
|
+
);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
What it does:
|
|
197
|
+
|
|
198
|
+
- Calls the OFSC `/resources` endpoint in pages of 100 records.
|
|
199
|
+
- Aggregates all returned items across all pages.
|
|
200
|
+
- Builds a union of all field names from the API payloads.
|
|
201
|
+
- Excludes nested relationship fields such as `links`, `inventories`, `users`,
|
|
202
|
+
`workZones`, `workSkills`, and `workSchedules` from the header set.
|
|
203
|
+
- Writes the result to `./resources.csv` in the current working directory.
|
|
204
|
+
- Serializes arrays under the `keys` field as pipe-delimited strings and JSON-serializes object values for CSV compatibility.
|
|
205
|
+
|
|
206
|
+
Signature:
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
downloadAllResourcesCSV(
|
|
210
|
+
clientId: string,
|
|
211
|
+
clientSecret: string,
|
|
212
|
+
instanceUrl: string,
|
|
213
|
+
): Promise<void>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### `AllResources`
|
|
217
|
+
|
|
218
|
+
Fetches all resources across all pages and returns them as a single flattened array.
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
const resources = await ofs.AllResources(
|
|
222
|
+
process.env.CLIENT_ID,
|
|
223
|
+
process.env.CLIENT_SECRET,
|
|
224
|
+
process.env.INSTANCE_NAME,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
console.log(`Found ${resources.length} resources`);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This helper is useful when you need to iterate through every resource object in memory, for analytics, reporting, or bulk transformations.
|
|
231
|
+
|
|
232
|
+
Signature:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
AllResources(
|
|
236
|
+
clientId: string,
|
|
237
|
+
clientSecret: string,
|
|
238
|
+
instanceUrl: string,
|
|
239
|
+
initialToken?: string,
|
|
240
|
+
): Promise<ResourceResponse[]>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Notes:
|
|
244
|
+
|
|
245
|
+
- It paginates automatically until all results are fetched.
|
|
246
|
+
- It returns the flattened `items` collection from every page rather than the raw API wrapper object.
|
|
247
|
+
- The optional `initialToken` parameter can be supplied if you already have a valid bearer token available and want to reuse it.
|
|
248
|
+
|
|
249
|
+
#### `getworkSkillsOfResource`
|
|
250
|
+
|
|
251
|
+
Retrieves all work skills assigned to a specific resource.
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
const result = await ofs.getworkSkillsOfResource(
|
|
255
|
+
process.env.CLIENT_ID,
|
|
256
|
+
process.env.CLIENT_SECRET,
|
|
257
|
+
process.env.INSTANCE_NAME,
|
|
258
|
+
12345,
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
console.log(result.data);
|
|
262
|
+
console.log(result.token);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
Signature:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
getworkSkillsOfResource(
|
|
270
|
+
clientId: string,
|
|
271
|
+
clientSecret: string,
|
|
272
|
+
instanceUrl: string,
|
|
273
|
+
resourceId: number,
|
|
274
|
+
token?: string,
|
|
275
|
+
): Promise<{ token: string; data: any }>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Return shape:
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
{
|
|
282
|
+
token: string,
|
|
283
|
+
data: any
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The `data` value is the `items` array returned by OFSC for the resource's work skills.
|
|
288
|
+
|
|
289
|
+
#### `getResourcebyId`
|
|
290
|
+
|
|
291
|
+
Fetches a single resource by its ID.
|
|
292
|
+
|
|
293
|
+
```js
|
|
294
|
+
const resource = await ofs.getResourcebyId(
|
|
295
|
+
"resource-123",
|
|
296
|
+
process.env.CLIENT_ID,
|
|
297
|
+
process.env.CLIENT_SECRET,
|
|
298
|
+
process.env.INSTANCE_NAME,
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
console.log(resource);
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
Signature:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
getResourcebyId(
|
|
310
|
+
resourceId: string,
|
|
311
|
+
clientId: string,
|
|
312
|
+
clientSecret: string,
|
|
313
|
+
instanceUrl: string,
|
|
314
|
+
initialToken?: string,
|
|
315
|
+
): Promise<ResourceResponse>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
The response is the raw OFSC resource payload returned by the API, so you can inspect its `items`, `totalResults`, and related metadata with the same structure returned by OFSC.
|
|
319
|
+
|
|
320
|
+
#### `updateResourcebyId`
|
|
321
|
+
|
|
322
|
+
Updates a resource record by ID using a PATCH request.
|
|
323
|
+
|
|
324
|
+
```js
|
|
325
|
+
const payload = {
|
|
326
|
+
name: "Updated Resource Name",
|
|
327
|
+
status: "ACTIVE",
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
const response = await ofs.updateResourcebyId(
|
|
331
|
+
"resource-123",
|
|
332
|
+
process.env.CLIENT_ID,
|
|
333
|
+
process.env.CLIENT_SECRET,
|
|
334
|
+
process.env.INSTANCE_NAME,
|
|
335
|
+
"",
|
|
336
|
+
payload,
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
console.log(response);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Signature:
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
updateResourcebyId(
|
|
346
|
+
resourceId: string,
|
|
347
|
+
clientId: string,
|
|
348
|
+
clientSecret: string,
|
|
349
|
+
instanceUrl: string,
|
|
350
|
+
initialToken?: string,
|
|
351
|
+
payload: object,
|
|
352
|
+
): Promise<ResourceResponse>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Notes:
|
|
356
|
+
|
|
357
|
+
- The payload is sent as a PATCH body to the OFSC resource update endpoint.
|
|
358
|
+
- It uses the same retry-wrapper logic as the other OFSC API methods so transient gateway and 5xx failures are retried automatically.
|
|
359
|
+
- The returned value is the API response payload from OFSC.
|
|
360
|
+
|
|
361
|
+
#### Example: working with a resource and its work skills
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
const resourceId = "resource-123";
|
|
365
|
+
|
|
366
|
+
const resource = await ofs.getResourcebyId(
|
|
367
|
+
resourceId,
|
|
368
|
+
process.env.CLIENT_ID,
|
|
369
|
+
process.env.CLIENT_SECRET,
|
|
370
|
+
process.env.INSTANCE_NAME,
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const workSkills = await ofs.getworkSkillsOfResource(
|
|
374
|
+
process.env.CLIENT_ID,
|
|
375
|
+
process.env.CLIENT_SECRET,
|
|
376
|
+
process.env.INSTANCE_NAME,
|
|
377
|
+
Number(resourceId),
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
console.log("Resource:", resource);
|
|
381
|
+
console.log("Work skills:", workSkills.data);
|
|
382
|
+
```
|
|
383
|
+
|
|
175
384
|
#### Download inactive users
|
|
176
385
|
|
|
177
386
|
`downloadAllInactiveUsersCSV` downloads all users from the OFSC Users API, filters
|
|
@@ -333,8 +542,177 @@ node scripts/test-download-inactive-users-data.js
|
|
|
333
542
|
|
|
334
543
|
`INACTIVITY_THRESHOLD_DAYS` is optional in the test script and defaults to `14`.
|
|
335
544
|
|
|
545
|
+
#### Get user by login
|
|
546
|
+
|
|
547
|
+
`getUserByLogin` fetches a single user record by login name and returns the raw OFSC response payload.
|
|
548
|
+
|
|
549
|
+
```js
|
|
550
|
+
const user = await ofs.getUserByLogin(
|
|
551
|
+
"user@example.com",
|
|
552
|
+
process.env.CLIENT_ID,
|
|
553
|
+
process.env.CLIENT_SECRET,
|
|
554
|
+
process.env.INSTANCE_NAME,
|
|
555
|
+
);
|
|
556
|
+
|
|
557
|
+
console.log(user);
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
**Function signature**
|
|
561
|
+
|
|
562
|
+
```ts
|
|
563
|
+
getUserByLogin(
|
|
564
|
+
login: string,
|
|
565
|
+
clientId: string,
|
|
566
|
+
clientSecret: string,
|
|
567
|
+
instanceUrl: string,
|
|
568
|
+
initialToken?: string,
|
|
569
|
+
): Promise<any>
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
Notes:
|
|
573
|
+
|
|
574
|
+
- This method is intended for standalone OFSC environments.
|
|
575
|
+
- The response is the raw OFSC user payload returned by the API.
|
|
576
|
+
- `initialToken` is optional and can be reused if a bearer token is already available.
|
|
577
|
+
|
|
578
|
+
#### Update user by login
|
|
579
|
+
|
|
580
|
+
`updateUserbyLogin` updates a user record by login using a PATCH request.
|
|
581
|
+
|
|
582
|
+
```js
|
|
583
|
+
const payload = {
|
|
584
|
+
firstName: "Updated",
|
|
585
|
+
lastName: "User",
|
|
586
|
+
status: "ACTIVE",
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
const response = await ofs.updateUserbyLogin(
|
|
590
|
+
"user@example.com",
|
|
591
|
+
process.env.CLIENT_ID,
|
|
592
|
+
process.env.CLIENT_SECRET,
|
|
593
|
+
process.env.INSTANCE_NAME,
|
|
594
|
+
"",
|
|
595
|
+
payload,
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
console.log(response);
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Function signature**
|
|
602
|
+
|
|
603
|
+
```ts
|
|
604
|
+
updateUserbyLogin(
|
|
605
|
+
login: string,
|
|
606
|
+
clientId: string,
|
|
607
|
+
clientSecret: string,
|
|
608
|
+
instanceUrl: string,
|
|
609
|
+
initialToken?: string,
|
|
610
|
+
payload: object,
|
|
611
|
+
): Promise<ResourceResponse>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Notes:
|
|
615
|
+
|
|
616
|
+
- The payload is sent as a PATCH body to the OFSC user update endpoint.
|
|
617
|
+
- It uses the same retry wrapper as the other OFSC API helpers.
|
|
618
|
+
- This method is also intended for standalone OFSC usage and may not behave the same in Fusion OFSC.
|
|
619
|
+
|
|
336
620
|
### Resource related methods
|
|
337
621
|
|
|
622
|
+
> Note: User and resource-related methods are applicable exclusively to standalone OFSC environments and are not supported in Fusion OFSC.
|
|
623
|
+
|
|
624
|
+
These methods are for standalone OFSC environments only. If you are connecting to Fusion OFSC, the user- and resource-based APIs may not behave the same way, and the request/response structure may not match the standalone endpoints.
|
|
625
|
+
|
|
626
|
+
#### Get all resources
|
|
627
|
+
|
|
628
|
+
`AllResources` retrieves all resources from the OFSC Resources API. Results are
|
|
629
|
+
fetched in pages of 100 records until every resource has been returned.
|
|
630
|
+
|
|
631
|
+
```js
|
|
632
|
+
const resources = await ofs.AllResources(
|
|
633
|
+
process.env.CLIENT_ID,
|
|
634
|
+
process.env.CLIENT_SECRET,
|
|
635
|
+
process.env.INSTANCE_NAME,
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
console.log(`Loaded ${resources.length} resources`);
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
**Function signature**
|
|
642
|
+
|
|
643
|
+
```ts
|
|
644
|
+
AllResources(
|
|
645
|
+
clientId: string,
|
|
646
|
+
clientSecret: string,
|
|
647
|
+
instanceUrl: string,
|
|
648
|
+
initialToken?: string,
|
|
649
|
+
): Promise<ResourceResponse[]>
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
`initialToken` is optional. The helper refreshes the token as needed while
|
|
653
|
+
requesting subsequent pages.
|
|
654
|
+
|
|
655
|
+
#### Get a resource by ID
|
|
656
|
+
|
|
657
|
+
`getResourcebyId` fetches a single resource by its resource ID and returns the
|
|
658
|
+
OFSC response envelope.
|
|
659
|
+
|
|
660
|
+
```js
|
|
661
|
+
const resource = await ofs.getResourcebyId(
|
|
662
|
+
"5457",
|
|
663
|
+
process.env.CLIENT_ID,
|
|
664
|
+
process.env.CLIENT_SECRET,
|
|
665
|
+
process.env.INSTANCE_NAME,
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
console.log(resource.items);
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
**Function signature**
|
|
672
|
+
|
|
673
|
+
```ts
|
|
674
|
+
getResourcebyId(
|
|
675
|
+
resourceId: string,
|
|
676
|
+
clientId: string,
|
|
677
|
+
clientSecret: string,
|
|
678
|
+
instanceUrl: string,
|
|
679
|
+
initialToken?: string,
|
|
680
|
+
): Promise<ResourceResponse>
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
The returned response contains `items`, `offset`, `limit`, and `totalResults`.
|
|
684
|
+
`initialToken` is optional.
|
|
685
|
+
|
|
686
|
+
#### Get resource work skills
|
|
687
|
+
|
|
688
|
+
`getworkSkillsOfResource` retrieves the work skills assigned to a resource.
|
|
689
|
+
The result includes the token returned by the request and the skills in `data`.
|
|
690
|
+
|
|
691
|
+
```js
|
|
692
|
+
const workSkills = await ofs.getworkSkillsOfResource(
|
|
693
|
+
process.env.CLIENT_ID,
|
|
694
|
+
process.env.CLIENT_SECRET,
|
|
695
|
+
process.env.INSTANCE_NAME,
|
|
696
|
+
5457,
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
console.log(workSkills.data);
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**Function signature**
|
|
703
|
+
|
|
704
|
+
```ts
|
|
705
|
+
getworkSkillsOfResource(
|
|
706
|
+
clientId: string,
|
|
707
|
+
clientSecret: string,
|
|
708
|
+
instanceUrl: string,
|
|
709
|
+
resourceId: number,
|
|
710
|
+
token?: string,
|
|
711
|
+
): Promise<{ token: string; data: any }>
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
`token` is optional. `data` contains the work-skill items returned by OFSC.
|
|
715
|
+
|
|
338
716
|
```js
|
|
339
717
|
await ofs.generateAllOnHandInventoryOfAllResourcesCSV(
|
|
340
718
|
process.env.CLIENT_ID,
|