Google apps script provides a library feature, where if you include the project key, a library is added as global object. I'm looking to iterate all functions of a added library. This used to be possible in rhino engine with a for...in loop. But I'm unable to iterate through any of the properties of to a library in v8 engine.
The documentation says
In the V8 runtime, a project and its libraries are run in different execution contexts and hence have different globals and prototype chains.
Can anyone explain how this object is created or how to access all it's properties?
Project A:
function testLib(prop = 'main') {
const isEnumerable = MyLibrary.propertyIsEnumerable(prop);
const isOwnProperty = MyLibrary.hasOwnProperty(prop);
console.info({ isEnumerable, isOwnProperty }); // { isEnumerable: false, isOwnProperty: true }
console.info(prop in MyLibrary);//true
for (const property in MyLibrary) {
//loop doesn't start
console.info(property);
}
console.info(Object.getOwnPropertyDescriptor(MyLibrary, prop)); //logs expected data:
/*{ value: [Function: main],
writable: true,
enumerable: false,
configurable: true }*/
console.log(Object.getOwnPropertyDescriptors(MyLibrary)); //actual: {} Expected: array of all functions including `main`
MyLibrary.a = 1;
console.log(Object.getOwnPropertyDescriptors(MyLibrary)); //actual: {a:1} Expected: array of all functions including `main`
}
function testPropDescriptors() {
const obj = { prop1: 1, b: 2 };
console.log(Object.getOwnPropertyDescriptors(obj)); //logs expected data
/*{prop1: { value: 1, writable: true, enumerable: true, configurable: true },
b: { value: 2, writable: true, enumerable: true, configurable: true } }*/
}
MyLibrary(Project B):
function main(){}
function onEdit(){}
To reproduce,
- Create a new project by clicking here - say, Project A
- Create a another script project(say Project B):
- add a function named
mainin Project B and - Deploy it by clicking deploy in top right.
- add it's key in project A and name it
MyLibrary.
- add a function named
- Copy paste the above script in Project A, select
testLibfunction and click run
Issue and workaround:
I had been looking for the methods for directly retrieving the properties and functions in the library side from the client-side under enabling V8. But unfortunately, I cannot still find it. So in my case, I use 2 workarounds.
Retrieve all scripts using Apps Script API and/or Drive API.
Wrapping the properties and functions in an object.
By the above workarounds, the properties and functions on the library side can be retrieved from the client-side.
Workaround 1:
In this workaround, all scripts on the library side are retrieved using Apps Script API and Drive API.
Sample script 1:
In this sample, Apps Script API is used. So, when you use this script, please link Google Cloud Platform Project to Google Apps Script Project. Ref And, please enable Apps Script API at API console.
When this script is used for your library script,
console.log(functions.flatMap(({functionSet}) => functionSet.values))returns[ { name: 'main' }, { name: 'onEdit' } ].In this case, even when the library is the container-bound script of Google Docs, this script can work.
Sample script 2:
In this sample, Drive API is used. So, when you use this script, please enable Drive API at Advanced Google services.
When this script is used for your library script,
console.log(functions)returns[ 'function main(){}\nfunction onEdit(){}\n' ].In this case, the function names are not automatically parsed. But Google Apps Script Project is not required to be linked with Google Cloud Platform Project. But, when the library is the container-bound script of Google Docs, this script cannot be used. In this case, when the library is only the standalone type, this script can be used. Please be careful about this.
Workaround 2:
In this workaround, the properties and functions in the library side are wrapped with an object.
Sample script: Library side
Sample script: Client side
console.log(res1)andconsole.log(res2)return{ method1: [Function: method1], method2: [Function: method2] }and[ 'constructor', 'method1' ], respectively.References: