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 parameterslet project = params.actualParams.project._list[0];//extracts the zip link for the scripts folder from the passed parametersconst { zipLink } = params.actualParams;//array that configs are pushed to laterlet configs = [];
//downloads the project setup zip fileconst response = await fetch(zipLink);//uses response.unZippedFilePath for the directory pathconst directoryPath = response.unZippedFilePath;//constructs the path to the scripts folderconst 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 UserConfiglet 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);