Include secondary sources in GJS - gnome

I am developing a Gnome extension. As such, I have an extension.js where all my code resides.
Now I have some other code I want to use, which lives in a file foo.js and sadly does not yet use strict mode. How can I load this foo.js?

This is covered in the existing tutorial:
// GJS's Built-in Modules are in the top-level
// See: https://gitlab.gnome.org/GNOME/gjs/blob/master/doc/Modules.md
const Gettext = imports.gettext;
const Cairo = imports.cairo;
// GNOME APIs are under the `gi` namespace (except Cairo)
// See: https://gjs-docs.gnome.org/
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
// GNOME Shell imports
const Main = imports.ui.main;
const ExtensionUtils = imports.misc.extensionUtils;
// You can import your modules using the extension object.
// For example, if you had a file named `exampleLib.js` in your extension directory
const Me = ExtensionUtils.getCurrentExtension();
const ExampleLib = Me.imports.exampleLib;
let myObject = new ExampleLib.ExportedClass();
ExampleLib.exportedFunction(0, ExampleLib.EXPORTED_VARIABLE);

Related

Node js - Issue with my syntax in require(module) . When to use {} and when not to use {} in require('module')

I have a query with the syntax in the require statement. Please refere the sample code below.
const nodemailer = require("nodemailer");
const {google} =require('googleapis');
const {OAuth2}=google.auth;
Some times , I see sample codes which use
const {<variable>} = require('moduleName')
Other times, I see like below
const <variable> = require('moduleName')
What is the difference between them?
Thanks in Advance.
Grateful to the Developers Community.
So, you use { } in this context when you want to do object destructuring to get a property from the exported object and create a module-level variable with that same name.
This:
const { google } = require('googleapis');
is a shortcut for this:
const __g = require('googleapis');
const google = __g.google;
So, within this context, you use the { google } only when you want the .google property from the imported module.
If you want the entire module handle such as this:
const nodemailer = require("nodemailer");
then, you don't use the { }. The only way to know which one you want for any given module is to consult the documentation for the module, the code for the module or examples of how to use the module. It depends entirely upon what the module exports and whether you want the top level export object or you want a property of that object.
It's important to realize that the { } used with require() is not special syntax associated with require(). This is normal object destructuring assignment, the same as if you did this:
// define some object
const x = { greeting: "hello" };
// use object destructuring assignment to create a new variable
// that contains the property of an existing object
const { greeting } = x;
console.log(greeting); // "hello
When you import the function with {}, it means you just import one function that available in the package. Maybe you have've seen:
const {googleApi, googleAir, googleWater} = require("googleapis")
But, when you not using {}, it means you import the whole package, just write:
const google = require("googleapis")
So, let say when you need googleApi in your code. You can call it:
google.googleApi

Node JS, exporting a class and cosumin it with different name

I'm using Node v14.4.0. I created a file and named it 'dao.js'. The file includes the following:
class AppDAO {
// some constructor and functions
}
module.exports = AppDAO
In my app.js file I load it using
const dao = require('./dao');
const db = new dao();
It works fine, but I don't know why, shouldn't I use the class name as I set it, "AppDAO", instead of "dao"?
This link as well as other links, do not help me in understanding how require modules works.
Is there something that I am missing?
You can do this
file dao.js
class AppDAO {
// some constructor and functions
}
exports.AppDAO = AppDAO;
and in app.js
const dao = require('./dao');
const db = new dao.AppDAO();
You are exporting the class from the file you are requiring, so you have to write it like this.
const dao = require('./dao');
const db = new dao.AppDAO();

how to parse a value to a 2Dtext in spark ar

I have an X value representing how much I open my mouth in spark AR. How can I show that X value into a 2d text?
I expect the text to show the Number value while running the effect.
You should use this script:
const Scene = require('Scene');
// Use export keyword to make a symbol available in scripting debug console
export const Diagnostics = require('Diagnostics');
// To use variables and functions across files, use export/import keyword
// export const animationDuration = 10;
// Use import keyword to import a symbol from another file
// import { animationDuration } from './script.js'
// To access scene objects
// const directionalLight = Scene.root.find('directionalLight0');
// To access class properties
// const directionalLightIntensity = directionalLight.intensity;
// To log messages to the console
Diagnostics.log('Console message logged from the script.');
const Patches = require('Patches');
const numberFormat = '{0}';
const number = Patches.getScalarValue('number');
Patches.setStringValue('value', number.format(numberFormat));
enter image description here

exports is not defined when running node.js script using vm in strict mode

I see this code in many modules:
var app = exports = module.exports = {};
But I have some problem executing these modules using Node.js VM in strict mode.
Here a demonstration:
var code = `
'use strict'; // Works if I remove this line
var app = exports = module.exports;
`;
var vm = require('vm');
var vmModule = { exports: {} };
var context = vm.createContext({
exports: vmModule.exports,
module: vmModule
});
var script = new vm.Script(code);
script.runInContext(context);
console.log("ok");
If I run this code I receive a exports is not defined error.
Without use strict the above code works fine.
Why a similar declaration works on a standard Node module but not inside a vm script? Should I declare the context in a different way?
As pointed by #mscdex this is probably an issue with node. See github.com/nodejs/node/issues/5344.
A possible workaround that seems to work (I hope without other implications) is to wrap all code inside an iife function:
const iifeCode = `(function(exports){${code}}(module.exports));`;
Then execute iifeCode instead of code:
var script = new vm.Script(iifeCode);

Get cordova package name from javascript hook

I am writing a cordova plugin with a node hook to run after_prepare .
This is for Android only.
From within this hook I need to get the cordova package name, so I can copy a file to the src/com/example/myproject folder (if the package is com.example.myproject).
If I know the package name I can make this path. I have it working hardcoded now but I need this to work with two different package names.
Is there a way to get the package name from within this code in the plugin hook?
module.exports = function(ctx){
var fs = ctx.requireCordovaModule('fs');
var path = ctx.requireCordovaModule('path');
var deferral = ctx.requireCordovaModule('q').defer();
//get package name here
//do other stuff
}
I have done a lot of research but have not been able to find this.
Thanks.
It doesn't look like it is available off of the context object, but you could try to parse the config.xml.
module.exports = function(context) {
var fs = require('fs');
var path = require('path');
var config_xml = path.join(context.opts.projectRoot, 'config.xml');
var et = context.requireCordovaModule('elementtree');
var data = fs.readFileSync(config_xml).toString();
var etree = et.parse(data);
console.log(etree.getroot().attrib.id);
};
The local-webserver plugin uses a similar strategy for reading config properties.
Here my compilation from different answers that works in 2021.
I use it to update some parameters in Xcode project for plugins compilation.
You can see that I am getting here app id and name from config.xml
And you can add it to after_prepare hook:
<hook src="scripts/addBuildSettingsToXcode.js" type="after_prepare" />
#!/usr/bin/env node
let fs = require('fs');
let xcode = require('xcode');
let path = require('path');
let et = require('elementtree');
module.exports = function (context) {
//console.log(context);
function addBuildPropertyToDebugAndRelease(prop, value) {
console.log('Xcode Adding ' + prop + '=' + value);
myProj.addBuildProperty(prop, value, 'Debug');
myProj.addBuildProperty(prop, value, 'Release');
}
function updateBuildPropertyToDebugAndRelease(prop, value) {
console.log('Xcode Updating ' + prop + '=' + value );
myProj.updateBuildProperty(prop, value, 'Debug');
myProj.updateBuildProperty(prop, value, 'Release');
}
// Getting app id and name from config.xml
let config_xml = path.join(context.opts.projectRoot, 'config.xml');
let data = fs.readFileSync(config_xml).toString();
let etree = et.parse(data);
let appId = etree.getroot().attrib.id ;
let appName = etree.getroot().find('name')['text'];
// Building project path
let projectPath = 'platforms/ios/' + appName + '.xcodeproj/project.pbxproj';
// Opening Xcode project and parsing it
myProj = xcode.project(projectPath);
myProj = myProj.parseSync();
// Common properties
addBuildPropertyToDebugAndRelease('DEVELOPMENT_TEAM', 'CGXXXXXXX');
addBuildPropertyToDebugAndRelease('CODE_SIGN_IDENTITY', '"Apple Development"');
// Compilation properties
addBuildPropertyToDebugAndRelease('ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES', 'YES');
// Save project file
fs.writeFileSync(projectPath, myProj.writeSync());
};

Resources