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 parameterslet project = params.actualParams.project._list[0];//extracts the zip link for the scripts folder from the passed parametersconst { zipLink } = params.actualParams;//array that user 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 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);