ofsc-utility 1.0.38 → 1.0.40
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/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/users/index.d.ts +2 -0
- package/dist/users/index.js +103 -26
- package/package.json +1 -1
- package/readme.md +169 -0
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { generateAllOnHandInventoryOfAllResources, generateAllOnHandInventoryOfA
|
|
|
14
14
|
export { getOAuthToken } from './oauthTokenService';
|
|
15
15
|
export { downloadWorkZoneCSV } from './workZones';
|
|
16
16
|
export { AllResources, downloadAllResourcesCSV, getworkSkillsOfResource } from './resources';
|
|
17
|
-
export { downloadAllInactiveUsersCSV, downloadAllUsersCSV, generateUsersCollaborationCSV } from './users';
|
|
17
|
+
export { downloadAllInactiveUsers, downloadAllInactiveUsersCSV, downloadAllUsersCSV, generateUsersCollaborationCSV } from './users';
|
|
18
18
|
export { downloadAllInventoryTypesCSV, getInventoryTypesDetail, updateCreateInventoryType } from './inventoryTypes';
|
|
19
19
|
export { getActivitybyId, getAllActivities } from './activities';
|
|
20
20
|
export { createActivityCustomerInventories, getActivityCustomerInventories } from './activityInventories';
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.createConfigurationFile = exports.createExcelFile = exports.downloadAllEventsOfLastOneHour = exports.downloadAllEventsOfDLastTwoMinutes = exports.downloadAllEventsOfDayCSV = exports.downloadAllEventsOfDay = exports.getActivityCustomerInventories = exports.createActivityCustomerInventories = exports.getAllActivities = exports.getActivitybyId = exports.updateCreateInventoryType = exports.getInventoryTypesDetail = exports.downloadAllInventoryTypesCSV = exports.generateUsersCollaborationCSV = exports.downloadAllUsersCSV = exports.downloadAllInactiveUsersCSV = exports.getworkSkillsOfResource = exports.downloadAllResourcesCSV = exports.AllResources = exports.downloadWorkZoneCSV = exports.getOAuthToken = exports.generateAllOnHandInventoryOfAllResourcesCSV = exports.generateAllOnHandInventoryOfAllResources = exports.WorkZone = exports.Utilities = exports.User = exports.Resource = exports.OauthTokenService = exports.CreateConfigurationFile = exports.InventoryType = exports.Inventory = exports.Events = exports.ActivityInventories = exports.Activity = void 0;
|
|
39
|
+
exports.createConfigurationFile = exports.createExcelFile = exports.downloadAllEventsOfLastOneHour = exports.downloadAllEventsOfDLastTwoMinutes = exports.downloadAllEventsOfDayCSV = exports.downloadAllEventsOfDay = exports.getActivityCustomerInventories = exports.createActivityCustomerInventories = exports.getAllActivities = exports.getActivitybyId = exports.updateCreateInventoryType = exports.getInventoryTypesDetail = exports.downloadAllInventoryTypesCSV = exports.generateUsersCollaborationCSV = exports.downloadAllUsersCSV = exports.downloadAllInactiveUsersCSV = exports.downloadAllInactiveUsers = exports.getworkSkillsOfResource = exports.downloadAllResourcesCSV = exports.AllResources = exports.downloadWorkZoneCSV = exports.getOAuthToken = exports.generateAllOnHandInventoryOfAllResourcesCSV = exports.generateAllOnHandInventoryOfAllResources = exports.WorkZone = exports.Utilities = exports.User = exports.Resource = exports.OauthTokenService = exports.CreateConfigurationFile = exports.InventoryType = exports.Inventory = exports.Events = exports.ActivityInventories = exports.Activity = void 0;
|
|
40
40
|
// Export all methods grouped by category
|
|
41
41
|
exports.Activity = __importStar(require("./activities"));
|
|
42
42
|
exports.ActivityInventories = __importStar(require("./activityInventories"));
|
|
@@ -63,6 +63,7 @@ Object.defineProperty(exports, "AllResources", { enumerable: true, get: function
|
|
|
63
63
|
Object.defineProperty(exports, "downloadAllResourcesCSV", { enumerable: true, get: function () { return resources_1.downloadAllResourcesCSV; } });
|
|
64
64
|
Object.defineProperty(exports, "getworkSkillsOfResource", { enumerable: true, get: function () { return resources_1.getworkSkillsOfResource; } });
|
|
65
65
|
var users_1 = require("./users");
|
|
66
|
+
Object.defineProperty(exports, "downloadAllInactiveUsers", { enumerable: true, get: function () { return users_1.downloadAllInactiveUsers; } });
|
|
66
67
|
Object.defineProperty(exports, "downloadAllInactiveUsersCSV", { enumerable: true, get: function () { return users_1.downloadAllInactiveUsersCSV; } });
|
|
67
68
|
Object.defineProperty(exports, "downloadAllUsersCSV", { enumerable: true, get: function () { return users_1.downloadAllUsersCSV; } });
|
|
68
69
|
Object.defineProperty(exports, "generateUsersCollaborationCSV", { enumerable: true, get: function () { return users_1.generateUsersCollaborationCSV; } });
|
package/dist/users/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ declare const OfscUserUtility: {
|
|
|
4
4
|
generateUsersCollaborationCSV: any;
|
|
5
5
|
downloadAllUsersCSV: typeof downloadAllUsersCSV;
|
|
6
6
|
downloadAllInactiveUsersCSV: typeof downloadAllInactiveUsersCSV;
|
|
7
|
+
downloadAllInactiveUsers: typeof downloadAllInactiveUsers;
|
|
7
8
|
};
|
|
8
9
|
export declare function downloadAllInactiveUsersCSV(clientId: string, clientSecret: string, instanceUrl: string, inactivityThresholdDays?: number): Promise<void>;
|
|
10
|
+
export declare function downloadAllInactiveUsers(clientId: string, clientSecret: string, instanceUrl: string, inactivityThresholdDays?: number): Promise<Record<string, any>[]>;
|
|
9
11
|
export default OfscUserUtility;
|
package/dist/users/index.js
CHANGED
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.generateUsersCollaborationCSV = void 0;
|
|
40
40
|
exports.downloadAllUsersCSV = downloadAllUsersCSV;
|
|
41
41
|
exports.downloadAllInactiveUsersCSV = downloadAllInactiveUsersCSV;
|
|
42
|
+
exports.downloadAllInactiveUsers = downloadAllInactiveUsers;
|
|
42
43
|
const fs = __importStar(require("fs"));
|
|
43
44
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
44
45
|
const index_1 = require("../oauthTokenService/index");
|
|
@@ -48,12 +49,12 @@ async function downloadAllUsersCSV(clientId, clientSecret, instanceUrl) {
|
|
|
48
49
|
const limit = 100;
|
|
49
50
|
let allItems = [];
|
|
50
51
|
let totalFetched = 0;
|
|
51
|
-
console.log("
|
|
52
|
+
console.log("Starting users download...");
|
|
52
53
|
console.log("-------------------------------------");
|
|
53
54
|
while (true) {
|
|
54
55
|
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/users/?offset=${offset}&limit=${limit}`;
|
|
55
56
|
const token = await (0, index_1.getOAuthToken)(clientId, clientSecret, instanceUrl);
|
|
56
|
-
console.log(
|
|
57
|
+
console.log(`Fetching offset=${offset} limit=${limit}`);
|
|
57
58
|
const res = await (0, node_fetch_1.default)(url, {
|
|
58
59
|
method: "GET",
|
|
59
60
|
headers: {
|
|
@@ -62,18 +63,18 @@ async function downloadAllUsersCSV(clientId, clientSecret, instanceUrl) {
|
|
|
62
63
|
}
|
|
63
64
|
});
|
|
64
65
|
if (!res.ok) {
|
|
65
|
-
throw new Error(
|
|
66
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
|
|
66
67
|
}
|
|
67
68
|
const data = (await res.json());
|
|
68
69
|
allItems.push(...data.items);
|
|
69
70
|
totalFetched += data.items.length;
|
|
70
|
-
console.log(`
|
|
71
|
+
console.log(` Received ${data.items.length} items (Total: ${totalFetched})`);
|
|
71
72
|
if (offset + limit >= data.totalResults)
|
|
72
73
|
break;
|
|
73
74
|
offset += limit;
|
|
74
75
|
}
|
|
75
76
|
console.log("-------------------------------------");
|
|
76
|
-
console.log("
|
|
77
|
+
console.log("Collecting all unique properties...");
|
|
77
78
|
// Collect union of all properties
|
|
78
79
|
const allProperties = new Set();
|
|
79
80
|
for (const item of allItems) {
|
|
@@ -84,7 +85,7 @@ async function downloadAllUsersCSV(clientId, clientSecret, instanceUrl) {
|
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
const headers = Array.from(allProperties);
|
|
87
|
-
console.log(
|
|
88
|
+
console.log(`Total unique fields: ${headers.length}`);
|
|
88
89
|
// Build CSV rows
|
|
89
90
|
const csvRows = [];
|
|
90
91
|
csvRows.push(headers.join(","));
|
|
@@ -109,11 +110,11 @@ async function downloadAllUsersCSV(clientId, clientSecret, instanceUrl) {
|
|
|
109
110
|
const filePath = "./users.csv";
|
|
110
111
|
fs.writeFileSync(filePath, csvRows.join("\n"));
|
|
111
112
|
console.log("-------------------------------------");
|
|
112
|
-
console.log("
|
|
113
|
-
console.log(
|
|
114
|
-
console.log(
|
|
115
|
-
console.log(
|
|
116
|
-
console.log(
|
|
113
|
+
console.log("Users CSV Created Successfully!");
|
|
114
|
+
console.log(`File: ${filePath}`);
|
|
115
|
+
console.log(`Total Records: ${totalFetched}`);
|
|
116
|
+
console.log(`Total Columns (Dynamic): ${headers.length}`);
|
|
117
|
+
console.log(`Date Time: ${new Date()}`);
|
|
117
118
|
console.log("-------------------------------------");
|
|
118
119
|
}
|
|
119
120
|
var collaborationGroups_1 = require("./collaborationGroups");
|
|
@@ -121,7 +122,8 @@ Object.defineProperty(exports, "generateUsersCollaborationCSV", { enumerable: tr
|
|
|
121
122
|
const OfscUserUtility = {
|
|
122
123
|
generateUsersCollaborationCSV: require('./collaborationGroups').generateUsersCollaborationCSV,
|
|
123
124
|
downloadAllUsersCSV,
|
|
124
|
-
downloadAllInactiveUsersCSV
|
|
125
|
+
downloadAllInactiveUsersCSV,
|
|
126
|
+
downloadAllInactiveUsers
|
|
125
127
|
};
|
|
126
128
|
/**
|
|
127
129
|
* Returns true if the user is "inactive":
|
|
@@ -141,12 +143,12 @@ async function downloadAllInactiveUsersCSV(clientId, clientSecret, instanceUrl,
|
|
|
141
143
|
const limit = 100;
|
|
142
144
|
let allItems = [];
|
|
143
145
|
let totalFetched = 0;
|
|
144
|
-
console.log("
|
|
146
|
+
console.log("Starting users download...");
|
|
145
147
|
console.log("-------------------------------------");
|
|
146
148
|
while (true) {
|
|
147
149
|
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/users/?offset=${offset}&limit=${limit}`;
|
|
148
150
|
const token = await (0, index_1.getOAuthToken)(clientId, clientSecret, instanceUrl);
|
|
149
|
-
console.log(
|
|
151
|
+
console.log(`Fetching offset=${offset} limit=${limit}`);
|
|
150
152
|
const res = await (0, node_fetch_1.default)(url, {
|
|
151
153
|
method: "GET",
|
|
152
154
|
headers: {
|
|
@@ -155,23 +157,23 @@ async function downloadAllInactiveUsersCSV(clientId, clientSecret, instanceUrl,
|
|
|
155
157
|
}
|
|
156
158
|
});
|
|
157
159
|
if (!res.ok) {
|
|
158
|
-
throw new Error(
|
|
160
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
|
|
159
161
|
}
|
|
160
162
|
const data = (await res.json());
|
|
161
163
|
allItems.push(...data.items);
|
|
162
164
|
totalFetched += data.items.length;
|
|
163
|
-
console.log(`
|
|
165
|
+
console.log(` Received ${data.items.length} items (Total: ${totalFetched})`);
|
|
164
166
|
if (offset + limit >= data.totalResults)
|
|
165
167
|
break;
|
|
166
168
|
offset += limit;
|
|
167
169
|
}
|
|
168
170
|
console.log("-------------------------------------");
|
|
169
|
-
console.log(
|
|
171
|
+
console.log(`Filtering inactive users (no login in last ${inactivityThresholdDays} days)...`);
|
|
170
172
|
const now = new Date();
|
|
171
173
|
const inactiveItems = allItems.filter(item => isInactiveUser(item, inactivityThresholdDays, now));
|
|
172
|
-
console.log(`
|
|
174
|
+
console.log(` ${inactiveItems.length} of ${allItems.length} users are inactive`);
|
|
173
175
|
console.log("-------------------------------------");
|
|
174
|
-
console.log("
|
|
176
|
+
console.log("Collecting all unique properties...");
|
|
175
177
|
// Collect union of all properties (from inactive users only)
|
|
176
178
|
const allProperties = new Set();
|
|
177
179
|
for (const item of inactiveItems) {
|
|
@@ -182,7 +184,7 @@ async function downloadAllInactiveUsersCSV(clientId, clientSecret, instanceUrl,
|
|
|
182
184
|
}
|
|
183
185
|
}
|
|
184
186
|
const headers = Array.from(allProperties);
|
|
185
|
-
console.log(
|
|
187
|
+
console.log(`Total unique fields: ${headers.length}`);
|
|
186
188
|
// Build CSV rows
|
|
187
189
|
const csvRows = [];
|
|
188
190
|
csvRows.push(headers.join(","));
|
|
@@ -207,12 +209,87 @@ async function downloadAllInactiveUsersCSV(clientId, clientSecret, instanceUrl,
|
|
|
207
209
|
const filePath = "./inactive_users.csv";
|
|
208
210
|
fs.writeFileSync(filePath, csvRows.join("\n"));
|
|
209
211
|
console.log("-------------------------------------");
|
|
210
|
-
console.log("
|
|
211
|
-
console.log(
|
|
212
|
-
console.log(
|
|
213
|
-
console.log(
|
|
214
|
-
console.log(
|
|
215
|
-
console.log(
|
|
212
|
+
console.log("Inactive Users CSV Created Successfully!");
|
|
213
|
+
console.log(`File: ${filePath}`);
|
|
214
|
+
console.log(`Total Fetched: ${totalFetched}`);
|
|
215
|
+
console.log(`Inactive Records (>${inactivityThresholdDays} days): ${inactiveItems.length}`);
|
|
216
|
+
console.log(`Total Columns (Dynamic): ${headers.length}`);
|
|
217
|
+
console.log(`Date Time: ${new Date()}`);
|
|
216
218
|
console.log("-------------------------------------");
|
|
217
219
|
}
|
|
220
|
+
async function downloadAllInactiveUsers(clientId, clientSecret, instanceUrl, inactivityThresholdDays = 14) {
|
|
221
|
+
let offset = 0;
|
|
222
|
+
const limit = 100;
|
|
223
|
+
let allItems = [];
|
|
224
|
+
let totalFetched = 0;
|
|
225
|
+
console.log("Starting users download...");
|
|
226
|
+
console.log("-------------------------------------");
|
|
227
|
+
while (true) {
|
|
228
|
+
const url = `https://${instanceUrl}.fs.ocs.oraclecloud.com/rest/ofscCore/v1/users/?offset=${offset}&limit=${limit}`;
|
|
229
|
+
const token = await (0, index_1.getOAuthToken)(clientId, clientSecret, instanceUrl);
|
|
230
|
+
console.log(`Fetching offset=${offset} limit=${limit}`);
|
|
231
|
+
const res = await (0, node_fetch_1.default)(url, {
|
|
232
|
+
method: "GET",
|
|
233
|
+
headers: {
|
|
234
|
+
Authorization: `Bearer ${token}`,
|
|
235
|
+
Accept: "application/json"
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
if (!res.ok) {
|
|
239
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
|
|
240
|
+
}
|
|
241
|
+
const data = (await res.json());
|
|
242
|
+
allItems.push(...data.items);
|
|
243
|
+
totalFetched += data.items.length;
|
|
244
|
+
console.log(` Received ${data.items.length} items (Total: ${totalFetched})`);
|
|
245
|
+
if (offset + limit >= data.totalResults)
|
|
246
|
+
break;
|
|
247
|
+
offset += limit;
|
|
248
|
+
}
|
|
249
|
+
console.log("-------------------------------------");
|
|
250
|
+
console.log(`Filtering inactive users (no login in last ${inactivityThresholdDays} days)...`);
|
|
251
|
+
const now = new Date();
|
|
252
|
+
// Skip users with blank/missing lastLoginTime (never-login users are ignored entirely)
|
|
253
|
+
const usersWithLogin = allItems.filter(item => !!(0, index_2.parseOFSCDate)(item.lastLoginTime));
|
|
254
|
+
const skippedNeverLoggedIn = allItems.length - usersWithLogin.length;
|
|
255
|
+
const inactiveItems = usersWithLogin.filter(item => isInactiveUser(item, inactivityThresholdDays, now));
|
|
256
|
+
console.log(` Skipped (never logged in / blank lastLoginTime): ${skippedNeverLoggedIn}`);
|
|
257
|
+
console.log(` ${inactiveItems.length} of ${usersWithLogin.length} users with login history are inactive`);
|
|
258
|
+
console.log("-------------------------------------");
|
|
259
|
+
console.log("Collecting all unique properties...");
|
|
260
|
+
// Collect union of all properties (from inactive users only)
|
|
261
|
+
const allProperties = new Set();
|
|
262
|
+
for (const item of inactiveItems) {
|
|
263
|
+
for (const key of Object.keys(item)) {
|
|
264
|
+
if (!["resources", "collaborationGroups", "resourceInternalIds", "links"].includes(key)) {
|
|
265
|
+
allProperties.add(key);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const headers = Array.from(allProperties);
|
|
270
|
+
console.log(`Total unique fields: ${headers.length}`);
|
|
271
|
+
// Build array of plain objects (one per inactive user)
|
|
272
|
+
const result = inactiveItems.map(item => {
|
|
273
|
+
const obj = {};
|
|
274
|
+
for (const field of headers) {
|
|
275
|
+
let value = item[field];
|
|
276
|
+
if (field === "keys") {
|
|
277
|
+
obj[field] = Array.isArray(value) ? value.join("|") : (value ?? "");
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
// Keep objects as objects (no JSON-stringify/escaping needed since this isn't CSV)
|
|
281
|
+
obj[field] = value !== undefined ? value : null;
|
|
282
|
+
}
|
|
283
|
+
return obj;
|
|
284
|
+
});
|
|
285
|
+
console.log("-------------------------------------");
|
|
286
|
+
console.log("Inactive Users Collected Successfully!");
|
|
287
|
+
console.log(`Total Fetched: ${totalFetched}`);
|
|
288
|
+
console.log(`Skipped (never logged in): ${skippedNeverLoggedIn}`);
|
|
289
|
+
console.log(`Inactive Records (>${inactivityThresholdDays} days): ${result.length}`);
|
|
290
|
+
console.log(`Total Columns (Dynamic): ${headers.length}`);
|
|
291
|
+
console.log(`Date Time: ${new Date()}`);
|
|
292
|
+
console.log("-------------------------------------");
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
218
295
|
exports.default = OfscUserUtility;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofsc-utility",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.40",
|
|
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
|
@@ -144,8 +144,176 @@ await ofs.downloadAllUsersCSV(
|
|
|
144
144
|
process.env.CLIENT_SECRET,
|
|
145
145
|
process.env.INSTANCE_NAME,
|
|
146
146
|
);
|
|
147
|
+
|
|
148
|
+
await ofs.downloadAllInactiveUsersCSV(
|
|
149
|
+
process.env.CLIENT_ID,
|
|
150
|
+
process.env.CLIENT_SECRET,
|
|
151
|
+
process.env.INSTANCE_NAME,
|
|
152
|
+
14,
|
|
153
|
+
);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Download inactive users
|
|
157
|
+
|
|
158
|
+
`downloadAllInactiveUsersCSV` downloads all users from the OFSC Users API, filters
|
|
159
|
+
the results, and writes the matching users to `./inactive_users.csv`.
|
|
160
|
+
|
|
161
|
+
A user is considered inactive when either:
|
|
162
|
+
|
|
163
|
+
- `lastLoginTime` is missing or cannot be parsed, or
|
|
164
|
+
- the time since `lastLoginTime` is greater than `inactivityThresholdDays`
|
|
165
|
+
|
|
166
|
+
The threshold defaults to `14` days. The comparison uses the current date and
|
|
167
|
+
time when the function runs. A user whose last login is exactly at the threshold
|
|
168
|
+
is not included because the function uses a strictly greater-than comparison.
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
const ofs = require("ofsc-utility");
|
|
172
|
+
|
|
173
|
+
async function downloadInactiveUsers() {
|
|
174
|
+
const clientId = process.env.CLIENT_ID;
|
|
175
|
+
const clientSecret = process.env.CLIENT_SECRET;
|
|
176
|
+
const instanceUrl = process.env.INSTANCE_NAME;
|
|
177
|
+
|
|
178
|
+
if (!clientId || !clientSecret || !instanceUrl) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
"Set CLIENT_ID, CLIENT_SECRET and INSTANCE_NAME before running this example",
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
await ofs.downloadAllInactiveUsersCSV(
|
|
185
|
+
clientId,
|
|
186
|
+
clientSecret,
|
|
187
|
+
instanceUrl,
|
|
188
|
+
14,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
downloadInactiveUsers().catch((error) => {
|
|
193
|
+
console.error("Failed to download inactive users:", error);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Function signature**
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
downloadAllInactiveUsersCSV(
|
|
202
|
+
clientId: string,
|
|
203
|
+
clientSecret: string,
|
|
204
|
+
instanceUrl: string,
|
|
205
|
+
inactivityThresholdDays?: number,
|
|
206
|
+
): Promise<void>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Parameters**
|
|
210
|
+
|
|
211
|
+
- `clientId`: OFSC OAuth client ID.
|
|
212
|
+
- `clientSecret`: OFSC OAuth client secret.
|
|
213
|
+
- `instanceUrl`: OFSC instance name only, such as `mycompany`. Do not include
|
|
214
|
+
`https://` or `.fs.ocs.oraclecloud.com`.
|
|
215
|
+
- `inactivityThresholdDays`: optional non-negative number of days. Defaults to
|
|
216
|
+
`14`.
|
|
217
|
+
|
|
218
|
+
**Output**
|
|
219
|
+
|
|
220
|
+
- File: `./inactive_users.csv`, relative to the process working directory.
|
|
221
|
+
- The CSV contains one row per inactive user.
|
|
222
|
+
- Nested fields such as `resources`, `collaborationGroups`,
|
|
223
|
+
`resourceInternalIds`, and `links` are excluded.
|
|
224
|
+
- The remaining columns are generated dynamically from the fields returned by
|
|
225
|
+
the API. `keys` arrays are joined with `|`; other objects are serialized as
|
|
226
|
+
JSON strings.
|
|
227
|
+
|
|
228
|
+
The helper retrieves users in pages of 100 records and requires valid OFSC API
|
|
229
|
+
credentials. It does not return the CSV contents; successful completion resolves
|
|
230
|
+
to `void`.
|
|
231
|
+
|
|
232
|
+
To run the repository test script against a built distribution:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run build
|
|
236
|
+
export CLIENT_ID=yourClientId
|
|
237
|
+
export CLIENT_SECRET=yourClientSecret
|
|
238
|
+
export INSTANCE_URL=yourInstanceName
|
|
239
|
+
export INACTIVITY_THRESHOLD_DAYS=14
|
|
240
|
+
node scripts/test-download-inactive-users.js
|
|
147
241
|
```
|
|
148
242
|
|
|
243
|
+
`INACTIVITY_THRESHOLD_DAYS` is optional in the test script and defaults to `14`.
|
|
244
|
+
|
|
245
|
+
#### Collect inactive users
|
|
246
|
+
|
|
247
|
+
`downloadAllInactiveUsers` downloads users from the OFSC Users API, filters out
|
|
248
|
+
users whose last login is within the inactivity threshold, and returns the
|
|
249
|
+
matching users as an array of plain objects. It does not create a CSV file.
|
|
250
|
+
|
|
251
|
+
Unlike `downloadAllInactiveUsersCSV`, users with a blank or unparsable
|
|
252
|
+
`lastLoginTime` are skipped. The threshold defaults to `14` days, and a user is
|
|
253
|
+
included only when the time since the last login is strictly greater than the
|
|
254
|
+
threshold.
|
|
255
|
+
|
|
256
|
+
```js
|
|
257
|
+
const ofs = require("ofsc-utility");
|
|
258
|
+
|
|
259
|
+
async function collectInactiveUsers() {
|
|
260
|
+
const users = await ofs.User.downloadAllInactiveUsers(
|
|
261
|
+
process.env.CLIENT_ID,
|
|
262
|
+
process.env.CLIENT_SECRET,
|
|
263
|
+
process.env.INSTANCE_NAME,
|
|
264
|
+
14,
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
console.log(`Collected ${users.length} inactive users`);
|
|
268
|
+
console.log(users[0]);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
collectInactiveUsers().catch((error) => {
|
|
272
|
+
console.error("Failed to collect inactive users:", error);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Function signature**
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
downloadAllInactiveUsers(
|
|
281
|
+
clientId: string,
|
|
282
|
+
clientSecret: string,
|
|
283
|
+
instanceUrl: string,
|
|
284
|
+
inactivityThresholdDays?: number,
|
|
285
|
+
): Promise<Record<string, any>[]>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Parameters and result**
|
|
289
|
+
|
|
290
|
+
- `clientId`: OFSC OAuth client ID.
|
|
291
|
+
- `clientSecret`: OFSC OAuth client secret.
|
|
292
|
+
- `instanceUrl`: OFSC instance name only, such as `mycompany`. Do not include
|
|
293
|
+
`https://` or `.fs.ocs.oraclecloud.com`.
|
|
294
|
+
- `inactivityThresholdDays`: optional non-negative number of days. Defaults to
|
|
295
|
+
`14`.
|
|
296
|
+
- The returned array contains one object per inactive user.
|
|
297
|
+
- Nested fields such as `resources`, `collaborationGroups`,
|
|
298
|
+
`resourceInternalIds`, and `links` are excluded.
|
|
299
|
+
- `keys` arrays are joined with `|`; other object values remain objects.
|
|
300
|
+
|
|
301
|
+
The helper retrieves users in pages of 100 records and requires valid OFSC API
|
|
302
|
+
credentials.
|
|
303
|
+
|
|
304
|
+
To run the repository test script against a built distribution:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npm run build
|
|
308
|
+
export CLIENT_ID=yourClientId
|
|
309
|
+
export CLIENT_SECRET=yourClientSecret
|
|
310
|
+
export INSTANCE_URL=yourInstanceName
|
|
311
|
+
export INACTIVITY_THRESHOLD_DAYS=14
|
|
312
|
+
node scripts/test-download-inactive-users-data.js
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
`INACTIVITY_THRESHOLD_DAYS` is optional in the test script and defaults to `14`.
|
|
316
|
+
|
|
149
317
|
### Resource related methods
|
|
150
318
|
|
|
151
319
|
```js
|
|
@@ -285,6 +453,7 @@ Top-level exports include:
|
|
|
285
453
|
- `downloadWorkZoneCSV`
|
|
286
454
|
- `downloadAllResourcesCSV`
|
|
287
455
|
- `downloadAllUsersCSV`
|
|
456
|
+
- `downloadAllInactiveUsersCSV`
|
|
288
457
|
- `generateAllOnHandInventoryOfAllResourcesCSV`
|
|
289
458
|
- `generateAllOnHandInventoryOfAllResources`
|
|
290
459
|
- `downloadAllInventoryTypesCSV`
|