Skip to main content
Version: v5.2

userConfigImports

The function userConfigImports is called from the project orchestrator and it reads the scripts in scripts/nextScriptEngine/scripts and uploads them as UserConfig types in the Item Service for your project's namespace.

scriptsDescriptors and configNames arrays​

userConfigDescriptors array​

The userConfigDescriptors array contains UserConfig type definitions for the configs in scripts/nextScriptEngine/userconfigs. This data is used to create the UserConfig item in the Item Service.

let userConfigDescriptors = [
{
_name: "DBM Contributor",
_shortName: "iaf_dbm_contrib_uc",
_description: "DBM Contributor User Config",
_userType: "ipa-dt",
},
...
];

configNames array​

An array that contains the file names of the project's user configs stored in scripts/nextScriptEngine/userconfigs.

const configNames = [
"iaf_dbm_contrib_uc",
"iaf_dbm_review_uc",
"iaf_dbm_projadmin_uc",
];

userGroupDescriptors array​

The userGroupDescriptors array contains UserGroup type definitions for the project. This data is used to create the UserGroup items in the Passport Service for the project's namespace.

let userGroupDescriptors = [
{
_name: "Proj Admin",
_shortName: "proj_admin",
_description: "Proj Admin User Group",
permissions: {
//accessAll creates an admin with access to everything
accessAll: true,
},
},
{
_name: "File Contributor",
_shortName: "file_contrib",
_description: "File Contributor User Group",
permissions: {
workspaces: [{ actions: ["READ", "EDIT"] }],
namedUserItems: [{ actions: ["READ", "EDIT"] }],
files: [{ actions: ["READ", "EDIT"] }],
},
},
...
];

userConfigToUserGroupMap​

Maps each UserConfig to a UserGroup:

let userConfigToUserGroupMap = [
{ userConfig: "iaf_dbm_contrib_uc", userGroup: "file_contrib" },
{ userConfig: "iaf_dbm_review_uc", userGroup: "file_reviewer" },
{ userConfig: "iaf_dbm_projadmin_uc", userGroup: "proj_admin" },
];

userConifgImports​

The userConifgImports function defines the project's user configurations as UserConfig items and creates them in the Passport Service for the project's namespace.

Script file selection​

The script file selection code differs for a one-click orchestrator setup and a VS code extension setup:

Orchestrator file selection​

First, the script downloads the user config directory:

//extracts the project from the passed parameters
let project = params.actualParams.project._list[0];
//extracts the zip link for the scripts folder from the passed parameters
const { zipLink } = params.actualParams;
//array that configs are pushed to later
let configs = [];

//downloads the project setup zip file
const response = await fetch(zipLink);
//uses response.unZippedFilePath for the directory path
const directoryPath = response.unZippedFilePath;
//constructs the path to the scripts folder
const filePath = `${directoryPath}/scripts`;

With the scripts folder downloaded, the readFilesRecursively function reads the content of each user config in the folder and its subfolders:

async function readFilesRecursively(dir) {
//uses fs.readdirSync to read the directory's contents
const files = await fs.readdirSync(dir);
for (const file of files) {
const filePath = `${dir}/${file}`;
//if the item does not have a file extension,
//it is a folder and the readFilesRecursively
//function is recursively called to read its files
if (!file.includes(".")) {
await readFilesRecursively(filePath); // Await the recursive call
} else {
try {
for (let i = 0; i < configNames.length; i++) {
//if the file name matches the file name at the
//same index of the configNames array, it reads
//the file contents and converts the array of UTF-8
//encoded bytes into a string, then an JSON object
const configName = configNames[i];
if (configName === file.split(".")[0]) {
const fileData = await fs.readFileSync(filePath);
const dataString = Utf8ArrayToStr(fileData);
const dataParsed = JSON.parse(dataString);
const configContent = JSON.stringify(dataParsed, null, 2);
//pushes an object with the config name and its corresponding
//string content to the empty configs array
configs.push({ configName, configContent });
}
}
} catch (error) {
throw error;
}
}
}
}

VS code file selection​

The script uses the IafLocalFile.selectFiles function from the UiUtils package to open a local file system selector window for the user to select the files to upload:

async userConfigsLoader(input, libraries, ctx) {
let { PlatformApi, UiUtils } = libraries
let proj = await PlatformApi.IafProj.getCurrent(ctx)

let configFiles = await UiUtils.IafLocalFile.selectFiles({ multiple: true, accept: ".json" })

The script extracts the file name for each user config file:

let configNames = _.map(configFiles, (f) => {
//get the first part of the file name without extensions
return _.split(f.name, '.')[0]
})

The script reads the file contents using IafLocalFile.loadEXPFiles:

//load content of the user configs
let configContents = await UiUtils.IafLocalFile.loadEXPFiles(configFiles)

A new array is created and consists of grouped arrays, created by pairing items in configNames and configContents by their index:

let configs = _.zip(configNames, configContents)

These are then mapped to new objects in the new configDefs array:

let configDefs = _.map(configs, (c) => {
return { configName: c[0], configContent: c[1] }
})

Adding user groups​

Then, the function adds the user groups defined in the userGroupDescriptors array to the Passport Service under the current project using IafProj.addUserGroups:

const res = await PlatformApi.IafProj.addUserGroups(
project,
userGroupDescriptors,
ctx
);

Adding config content to UserConfig definition​

The function finds the UserConfig item definition that matches an item in the configs array and adds its config content:

let configItems = [];
configs.forEach((c) => {
let item = userConfigDescriptors.find(
(obj) => obj._shortName === c.configName
);
if (item) {
item._version = { _userData: c.configContent };
configItems.push(item);
}
});

Mapping UserGroup to UserConfig definition​

The function finds the UserGroup mapped to each UserConfig in userConfigToUserGroupMap and adds it to the groupItems array:

//Look up the UserGroup mapped to each UserConfig
let groupItems = [];
configs.forEach((c) => {
let group = userConfigToUserGroupMap.find(
(obj) => obj.userConfig === c.configName
);
let item = res.find((obj) => obj._shortName === group.userGroup);
if (item) {
groupItems.push(item);
}
});

Posting the UserConfigs​

Finally, the function creates the UserConfig items in the Item Service for a given UserGroup and resolves the promise:

for (let i = 0; i < configItems.length; i++) {
const userConfig = configItems[i];
const userGroup = groupItems[i];
const addUserConfigResult =
await PlatformApi.IafUserGroup.addUserConfigs(
userGroup,
[userConfig],
ctx
);
console.log(
"AddUserConfigs Response:",
userConfig._name,
userGroup._name,
addUserConfigResult
);
}
console.log("Completed userConifgImports", configNames);
resolve(configNames);