In Node.js, how can a module get data from an application's package.json? - json

I have a module. Inside it, I'd like to access data from my parent application's package.json file. What's the best practice way to do that?
I've done this the janky way by going up 2 levels and requiring the file (or using the nconf configuration loader).
var appdir = path.resolve(__dirname, '../../');
nconf.file('app', path.join(appdir, 'package.json'));
But that seems like it could break easily.
Also I heard about pkginfo, it will automatically grab info from my own module's package.json, but I'm looking to get data from the parent application's.
Thanks for any help!
EDIT: I suppose another way of asking is, how can I get the application's path (instead of the module path) ?

You can use
require.main.require './package'
But it'll work only if your parent application's file is in a root of it's directory.
You can also wrap it into try ... catch and add ../ to path till you find package.json.
You can read more about accessing main module here http://nodejs.org/api/modules.html#modules_accessing_the_main_module

Adding to pcru's approach, this should work:
function loadMainPackageJSON(attempts) {
attempts = attempts || 1;
if (attempts > 5) {
throw new Error('Can\'t resolve main package.json file');
}
var mainPath = attempts === 1 ? './' : Array(attempts).join("../");
try {
return require.main.require(mainPath + 'package.json');
} catch (e) {
return loadMainPackageJSON(attempts + 1);
}
}
var packageJSON = loadMainPackageJSON();
Keep in mind that this will get you the main module, which something you think is what you want , but if you're building a command line tool like I was, what you really want is to get the package.json exactly two folders above where you were installed if your tool is meant to be installed locally and called with npm run-script

As mentioned in Determine project root from a running node.js application , one of the easiest ways to get to your application path is using process.cwd(), provided you have the discipline to always start your main js program from the same directory. i.e. node app/main.js and cd app && node main.js will give different results.
Another way could be to recursively follow the references to module.parent, then read out module.filename when module.parent is undefined. This also presupposes some knowledge about your app. It won't work if the location of the main script relative to the package.json could vary. I.e. you must know if the main script is in the root of the app directory, or maybe in some sort of 'bin', 'app', or 'lib' dir. However, once you find the top-level module, you could try to locate the closest package.json using the same algorithm pkginfo uses to find the package.json for the current file.

Related

Cannot find module 'Scene' or its corresponding type declarations Spark AR

Anyone has any idea why do I get these errors? It's the first time when I'm trying to write a script, do I need to setup something first? Because from what I found in their documentation, there is no need..
Cannot find module 'Scene' or its corresponding type declarations.ts(2307)
Cannot find module 'Patches' or its corresponding type declarations.ts(2307)
Cannot find module 'Diagnostics' or its corresponding type declarations.ts(2307)
Thank you for your time!
LATER EDIT: it seems that this doesn't affect the script, because I can use functions like:
Diagnostics.log('Hello world!');
or
const [directionalLight] = await Promise.all([
Scene.root.findFirst('directionalLight0')
]);
(maybe Visual Studio was waiting for a file similar to package.json from npm)
Try to reopen all SparkAR and VSCode. It's crucial to open your script from inside SparkAR, then it should create tsconfig.json with all typings you need.

browserstack+nightwatch custom commands configuration

I have a Nightwatch + BrowserStack configuration on my project and I'm trying to add custom commands to my project to compare 2 screenshots using resemble.js .
I configure my nightwatch.json file with this :
"custom_commands_path": "./node_modules/nightwatch/commands",
"custom_assertions_path": "./node_modules/nightwatch/assertions"
I put the commands file in the folder and I tried to run my test in every directory possible to see if it was a path problem. I've also tried with different commands, some of them I get online and even the default example one. Whatever I run it returns nameOfTheCommand is not a function. So I guess it does not even find the path to the customs commands in the nightwatch.json file.
Is there anything I'm missing here? I'm quite new so the answer could be very simple but I tried every .json file of my project in case there was a special configuration linked to BrowserStack.
Path to the custom commands should be analogous to the path to custom commands. You should point a folder where you added them.
I've found that if I put them in the suite configuration file, it picks them up:
nightwatch_config = {
src_folders: ["tests/suite/product/"],
page_objects_path: "pages/product",
custom_commands_path: "./custom_commands"
}

immutable flow fails . live test on travis

Hello this questions is having a minimal working example of what Im trying to build.
Im having troubles to run flow-type checker on just simple JS file. Here is how the file looks like
// #flow
import type { Map } from 'immutable';
And I even build a minimal working (NOT working) example with travis running it.
Here is the repository. It's very simple and only has flow and immutable-js dependencies.
https://github.com/RusAlex/immutable-flow
and here is the failed Travis-ci build
https://travis-ci.org/RusAlex/immutable-flow/builds/243260858
Flow reads the package.json to find out about imports, but since you moved your .flowconfig inside your src/ folder, it no longer can. If you include the package.json by adding ../package.json to your [include] you get an interesting error:
src/flow.js:2
2: import { Map } from 'immutable';
^^^^^^^^^^^ This modules resolves to "<<PROJECT_ROOT>>/../node_modules/immutable/package.json", which is outside both your root directory and all of the entries in the [include] section of your .flowconfig. You should either add this directory to the [include] section of your .flowconfig, move your .flowconfig file higher in the project directory tree, or move this package under your Flow root directory.
Finally, adding ../node_modules/immutable/ will help flow resolve everything again.
Alternatively, you could just add .flowconfig to the actual project root. It makes things simpler and seems to be the intended default.

ViewHelper is not found

I fiddled around with it for more than 8 hours without getting it resolved.
All I want is to call a ViewHelper in a Fluid template. I did that before and I never had a similar problem.
My ViewHelper file is located in
EXTDIR/VendorName/Classes/ViewHelpers/SomeViewHelper.php.
In my Fluid Template I use the namespace
{namespace k=VendorName\Extname\ViewHelpers}.
Somewhere in the template I call the ViewHelper with
{k:some()}.
The ViewHelper script "SomeViewHelper.php" contains the following code:
class SomeViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
public function initializeArguments() { }
public function render() {
return 7;
}
}
As you can see, the whole thing is quite simple and the expected output on the page should be "7". But calling a page in the frontend produces this error message:
Oops, an error occurred!
Could not analyse class:VendorName\Extname\ViewHelpers\SomeViewHelper maybe not loaded
or no autoloader?"
Any hints on what might be wrong here?
Cheers
Michael
If everything is spelled correct, and even after deleting System/Configuration Cache the ViewHelper doesn't come up (Could not analyse.. / maybe not loaded or no autoloader), try to reinstall the extension in extension manager!
Your path to the viewHelper source file is wrong.
The correct path should be (without vendorname):
EXTDIR/Classes/ViewHelpers/SomeViewHelper.php
You also need to make sure, you use the correct namespace for your viewHelper (if you're on TYPO3 6+, don't use the old Tx_ classes but namespaces).
<?php
namespace VendorName\Extname\ViewHelpers;
class SomeViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
public function initializeArguments() { }
public function render() {
return 7;
}
}
The error message seems to indicate that the class is not found.
Without more info, I would probably suspect a typo somewhere (pun not intended).
The following assumes you are using TYPO3 7 and not composer mode:
First, please check if your viewhelper class is autoloaded. This will help to narrow down the problem. On the command line in the htdocs directory: grep SomeViewHelper typo3temp/autoload/autoload_classmap.php This should give you a hit, if the ViewHelper class is included in the autoload file.
If the classes are not autoloaded, you might manually want to do the autoloading: On the command line in the htdocs directory: php typo3/cli_dispatch.phpsh extbase extension:dumpclassloadinginformation
For more information see: https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Autoloading/Index.html. For more in depth info see this: http://insight.helhum.io/post/130876393595/how-to-configure-class-loading-for-extensions-in You can find this functionality of autoloading in the install tool in TYPO3 8, so in that case you would not need to run the command on the command line.
If this does not work either, check the following:
Are you using namespace correctly in the class: <?php namespace VendorName\Extname\ViewHelpers\SomeViewHelper;
Is the path (including Camelcase class name) correct: /Classes/ViewHelpers/SomeViewHelper.php
After that, clear the system cache and reinitiate the autoloading as described above.
In order for the autoloading to be initiated automatically, you might have to update your ext_emconf.php (if you are not using composer mode) or composer.json (if you are using composer mode).
Just some questions:
Did you add the TypoScript Template of the Extension to the Static Includes?
If you're using a unix-alike system, are you sure that your webserver has the permission to read that files?
If TYPO3 is installed in composer mode and your extension is not installed via composer (e.g. a ProviderExtension of FluidTYPO3), you must provide autoload information for your extension in the main composer.json file, as described within TYPO3-composer-documentation:
In Composer Mode all class loading information must be provided by each of the installed extensions or the root package. If TYPO3 extensions are not installed by composer, e.g. because they are directly committed to the root package or a new package is kickstarted, class loading information needs to be provided, otherwise no classes can be loaded for these extensions/ packages.
E.g. if you have a site extension directly committed to your root package, you must include the class loading information in the root package like that:
Drove me crazy to get my ViewHelpers autoloaded. Providing the autoload-information within a composer.json or the ext_emconf.php of the extension and reinstalling it didn't do the trick.

Get the application's path

I've recently searched how I could get the application's directory in Java. I've finally found the answer but I've needed surprisingly long because searching for such a generic term isn't easy. I think it would be a good idea to compile a list of how to achieve this in multiple languages.
Feel free to up/downvote if you (don't) like the idea and please contribute if you like it.
Clarification:
There's a fine distinction between the directory that contains the executable file and the current working directory (given by pwd under Unix). I was originally interested in the former but feel free to post methods for determining the latter as well (clarifying which one you mean).
In Java the calls
System.getProperty("user.dir")
and
new java.io.File(".").getAbsolutePath();
return the current working directory.
The call to
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
returns the path to the JAR file containing the current class, or the CLASSPATH element (path) that yielded the current class if you're running directly from the filesystem.
Example:
Your application is located at
C:\MyJar.jar
Open the shell (cmd.exe) and cd to C:\test\subdirectory.
Start the application using the command java -jar C:\MyJar.jar.
The first two calls return 'C:\test\subdirectory'; the third call returns 'C:\MyJar.jar'.
When running from a filesystem rather than a JAR file, the result will be the path to the root of the generated class files, for instance
c:\eclipse\workspaces\YourProject\bin\
The path does not include the package directories for the generated class files.
A complete example to get the application directory without .jar file name, or the corresponding path to the class files if running directly from the filesystem (e.g. when debugging):
String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
if (applicationDir.endsWith(".jar"))
{
applicationDir = new File(applicationDir).getParent();
}
// else we already have the correct answer
In .NET (C#, VB, …), you can query the current Assembly instance for its Location. However, this has the executable's file name appended. The following code sanitizes the path (using System.IO and using System.Reflection):
Directory.GetParent(Assembly.GetExecutingAssembly().Location)
Alternatively, you can use the information provided by AppDomain to search for referenced assemblies:
System.AppDomain.CurrentDomain.BaseDirectory
VB allows another shortcut via the My namespace:
My.Application.Info.DirectoryPath
In Windows, use the WinAPI function GetModuleFileName(). Pass in NULL for the module handle to get the path for the current module.
Python
path = os.path.dirname(__file__)
That gets the path of the current module.
Objective-C Cocoa (Mac OS X, I don't know for iPhone specificities):
NSString * applicationPath = [[NSBundle mainBundle] bundlePath];
In Java, there are two ways to find the application's path. One is to employ System.getProperty:
System.getProperty("user.dir");
Another possibility is the use of java.io.File:
new java.io.File("").getAbsolutePath();
Yet another possibilty uses reflection:
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
In VB6, you can get the application path using the App.Path property.
Note that this will not have a trailing \ EXCEPT when the application is in the root of the drive.
In the IDE:
?App.Path
C:\Program Files\Microsoft Visual Studio\VB98
In .Net you can use
System.IO.Directory.GetCurrentDirectory
to get the current working directory of the application, and in VB.NET specifically you can use
My.Application.Info.DirectoryPath
to get the directory of the exe.
Delphi
In Windows applications:
Unit Forms;
path := ExtractFilePath(Application.ExeName);
In console applications:
Independent of language, the first command line parameter is the fully qualified executable name:
Unit System;
path := ExtractFilePath(ParamStr(0));
Libc
In *nix type environment (also Cygwin in Windows):
#include <unistd.h>
char *getcwd(char *buf, size_t size);
char *getwd(char *buf); //deprecated
char *get_current_dir_name(void);
See man page
Unix
In unix one can find the path to the executable that was started using the environment variables. It is not necessarily an absolute path, so you would need to combine the current working directory (in the shell: pwd) and/or PATH variable with the value of the 0'th element of the environment.
The value is limited in unix though, as the executable can for example be called through a symbolic link, and only the initial link is used for the environment variable. In general applications on unix are not very robust if they use this for any interesting thing (such as loading resources). On unix, it is common to use hard-coded locations for things, for example a configuration file in /etc where the resource locations are specified.
In bash, the 'pwd' command returns the current working directory.
In PHP :
<?php
echo __DIR__; //same as dirname(__FILE__). will return the directory of the running script
echo $_SERVER["DOCUMENT_ROOT"]; // will return the document root directory under which the current script is executing, as defined in the server's configuration file.
echo getcwd(); //will return the current working directory (it may differ from the current script location).
?>
in Android its
getApplicationInfo().dataDir;
to get SD card, I use
Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(String type);
where the latter is used to store a specific type of file (Audio / Movies etc). You have constants for these strings in Environment class.
Basically, for anything to with app use ApplicationInfo class and for anything to do with data in SD card / External Directory using Environment class.
Docs :
ApplicationInfo ,
Environment
In Tcl
Path of current script:
set path [info script]
Tcl shell path:
set path [info nameofexecutable]
If you need the directory of any of these, do:
set dir [file dirname $path]
Get current (working) directory:
set dir [pwd]
Java:
On all systems (Windows, Linux, Mac OS X) works for me only this:
public static File getApplicationDir()
{
URL url = ClassLoader.getSystemClassLoader().getResource(".");
File applicationDir = null;
try {
applicationDir = new File(url.toURI());
} catch(URISyntaxException e) {
applicationDir = new File(url.getPath());
}
return applicationDir;
}
in Ruby, the following snippet returns the path of the current source file:
path = File.dirname(__FILE__)
In CFML there are two functions for accessing the path of a script:
getBaseTemplatePath()
getCurrentTemplatePath()
Calling getBaseTemplatePath returns the path of the 'base' script - i.e. the one that was requested by the web server.
Calling getCurrentTemplatePath returns the path of the current script - i.e. the one that is currently executing.
Both paths are absolute and contain the full directory+filename of the script.
To determine just the directory, use the function getDirectoryFromPath( ... ) on the results.
So, to determine the directory location of an application, you could do:
<cfset Application.Paths.Root = getDirectoryFromPath( getCurrentTemplatePath() ) />
Inside of the onApplicationStart event for your Application.cfc
To determine the path where the app server running your CFML engine is at, you can access shell commands with cfexecute, so (bearing in mind above discussions on pwd/etc) you can do:
Unix:
<cfexecute name="pwd"/>
for Windows, create a pwd.bat containing text #cd, then:
<cfexecute name="C:\docume~1\myuser\pwd.bat"/>
(Use the variable attribute of cfexecute to store the value instead of outputting to screen.)
In cmd (the Microsoft command line shell)
You can get the name of the script with %* (may be relative to pwd)
This gets directory of script:
set oldpwd=%cd%
cd %0\..
set app_dir=%pwd%
cd %oldpwd%
If you find any bugs, which you will. Then please fix or comment.
I released https://github.com/gpakosz/whereami which solves the problem in C and gives you:
the path to the current executable
the path to the current module (differs from path to executable when calling from a shared library).
It uses GetModuleFileNameW on Windows, parses /proc/self/maps on Linux and Android and uses _NSGetExecutablePath or dladdr on Mac and iOS.
Note to answer "20 above regarding Mac OSX only: If a JAR executable is transformed to an "app" via the OSX JAR BUNDLER, then the getClass().getProtectionDomain().getCodeSource().getLocation(); will NOT return the current directory of the app, but will add the internal directory structure of the app to the response. This internal structure of an app is /theCurrentFolderWhereTheAppReside/Contents/Resources/Java/yourfile
Perhaps this is a little bug in Java. Anyway, one must use method one or two to get the correct answer, and both will deliver the correct answer even if the app is started e.g. via a shortcut located in a different folder or on the desktop.
carl
SoundPimp.com