Skip to main content
Version: v5.0

uploadScripts

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

scriptsDescriptors and scriptNames arrays

scriptsDescriptors array

The scriptsDescriptors array contains Script type definitions for the scripts in scripts/nextScriptEngine/scripts. This data is used to create the Script item in the Item Service.

let scriptsDescriptors = [
{
_name: "Load Project Collection Data",
_shortName: "iaf_dt_proj_colls",
_description: "Load All Project Collections",
_userType: "iaf_dt_proj_colls",
},
...
]

scriptNames array

The scriptNames array contains the names of the script files in scripts/nextScriptEngine/scripts without their file extensions. The index order of the scriptNames array must match that of the scriptsDescriptors array.

const scriptNames = [
"iaf_dt_proj_colls",
...
];

uploadScripts

The uploadScripts function defines the project's object model scripts as Script items and creates them in the Item 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, it downloads the script 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 user 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 script in the folder and its subfolders:

await readFilesRecursively(filePath);

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 < scriptNames.length; i++) {
//if the file name matches the file name at the
//same index of the scriptNames array, it reads
//the file contents and converts the array of UTF-8
//encoded bytes into a string
const fileData = await fs.readFileSync(filePath);
const scriptName = scriptNames[i];
if (scriptName === file.split(".")[0]) {
const scriptContent = Utf8ArrayToStr(fileData);
//pushes an object with the script name and its corresponding
//string content to the empty scripts array
scripts.push({ scriptName, scriptContent });
}
}
} catch (error) {
null;
}
}
}
}

VScode extension 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 uploadScripts(input, libraries, ctx) {
let { PlatformApi, UiUtils } = libraries
let proj = await PlatformApi.IafProj.getCurrent(ctx)
//accepts multiple .js files
let scriptFiles = await UiUtils.IafLocalFile.selectFiles({ multiple: true, accept: ".js" })

The script extracts the file name for each script file:

let scriptNames = _.map(scriptFiles, (f) => {
return _.split(f.name, '.')[0]
})

The script reads the file contents using IafLocalFile.loadFiles:

let scriptContents = await UiUtils.IafLocalFile.loadFiles(scriptFiles)

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

let scripts = _.zip(scriptNames, scriptContents)
console.log("scripts", scripts);

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

let scriptDefs = _.map(scripts, (s) => {
return { scriptName: s[0], scriptContent: s[1] }
})

Adding script content to Script definition

The script finds the Script item definition that matches an item in the scripts array and adds its script content and the project's namespace:

let scriptItems = [];
scripts.forEach((c) => {
let item = scriptsDescriptors.find(
(obj) => obj._shortName === c.scriptName
);
if (item) {
//adds script content to a created property, _version._userData
item._version = { _userData: c.scriptContent };
//adds the project's namespace to the Script item definition
item._namespaces = project._namespaces;
scriptItems.push(item);
}
});

With the Script items defined, it passes them as an argument to IafScripts.create to create them as Script items in the Item Service and resolve the promise:

let createScriptRes = await PlatformApi.IafScripts.create(
scriptItems,
ctx
);
console.log("Created Scripts", createScriptRes);
resolve(createScriptRes);