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);