How to read Meteor settings from a build plugin - meteor

I'm currently working on a package for Meteor that includes a build plugin. I need to access configurations from the settings file.
However Meteor.settings doesn't work (Meteor is not defined) and process.env.METEOR_SETTINGS also doesn't exist.
Is there any way for my plugin to access the settings file?

It appears that despite the documentation discussing the use of --settings, it doesn't work in a production environment, as often command line options are not available.
So the solution is to use environment variables, which are available only on the server.
server code, meteor methods:
eor methods
Meteor.methods({
getPJS: function() {
return process.env.PEERJS_SERVER;
},
client code
var PJS = Meteor.call("getPJS");
So you can make those environment variables available on the client if you need them.

Related

Meteor: session-client-side

So im trying to build ontop of the angular-meteor WhatsApp clone tutorial using Ionic 2 CLI
This tutorial basically deletes the client folder in the meteor project and uses the meteor-client-side package inside an ionic project to connect to the meteor server.
Which works perfectly fine, but now i'd like to subscribe to a meteor publication with an reactive parameter.
After searching the Meteor API Documentation I found the Session object:
Session provides a global object on the client that you can use to
store an arbitrary set of key-value pairs. Use it to store things like
the currently selected item in a list.
What’s special about Session is that it’s reactive. If you
call Session.get("currentList") from inside a template, the template
will automatically be rerendered whenever 
Session.set("currentList", x) is called.
In the Meteor Subscribe Documentation you can find the following example:
Tracker.autorun(function () {
Meteor.subscribe("chat", {room: Session.get("current-room")});
Meteor.subscribe("privateMessages");
});
This subscribes you to the chat messages in the current room and to
your private messages. When you change rooms by
calling Session.set("current-room", "new-room"), Meteor will subscribe
to the new room’s chat messages, unsubscribe from the original room’s
chat messages, and continue to stay subscribed to your private
messages.
Which is exactly what I want to do too. But as the Session documentation states, session is a package I have to add to the meteor project:
To add Session to your application, run this command in your terminal:
meteor add session
Now my question, is there any way to add session to the meteor-client-side packages?
If I just try to call Session.set() it fails on runtime with Session is not defined
My guess is that I would need some npm package that extracts the Session functionality (basically a sessions-client-side npm package) like accounts-base-client-side
Is there an other way to do this?
How would I build my own sessions-client-side?
I tried to run meteor add session in my meteor project but was not able to find the code for Session anywhere in .meteor folder and npm_modules.
I also looked into the meteor GitHub but the Session.js file they have contains only documentation
Any input how to do something like this would be nice
Update:
I've looked into the accounts-base-client-side package and found out that they are autogenerated using a script, so im currently trying to adapt this script to work with Session instead of accounts-base.
You can find my attempt at: https://github.com/AwsmOli/session-client-side
Still work in progress, but i should get it to work soon
Update 2:
See my answer, my session-client-side is working now :)
The "Session" variable should just appear and be accessible. If you need to verify that, start a new project add the package and write some code to access it. It is likely that something has (unwittingly) nuked the Session variable - I have seen this before with another package.
Another way of doing this is with "getReactively". Below is a helper that uses it in a query. Make sure you declare it before the helper (otherwise it won't work). This one uses the result of another helper, but it can be any variable, and you just assign the variable for the reactivity to kick in and run the helper.
this.helpers({
currentUser: () => { return Meteor.user() },
elder: () => {
let e = Elders.findOne({_id: this.getReactively('this.currentUser._id')});
if (e) {
utils.services.setupElder(e);
}
return e;
}
});
As per the meteor docs, you have to import it:
import { Session } from 'meteor/session'
This will enable it on the client.
In earlier meteor versions this was not required, as it was both a default package, and automatically imported into the global namespace.
I ended up creating the session-client-side package myself, and its working nicely.
If you need it too, its available on GitHub:
https://github.com/AwsmOli/session-client-side
and NPM:
npm install session-client-side
credits to idanwe who created the client side packages and made it realy easy to adapt his work to work with any meteor package :)
To use it with Ionic 2 Apps:
import it in your entry points (src/app/main.prod.ts & src/app/main.dev.ts)
import 'session-client-side';
and now the global Session variable is accessable form anywhere in your app:
Session.set("aCoolNameFormyAwsmChangingObject", myAwsmChangingObject);
Thanks for the help!

Meteor with dotenv package for environment variables: "process" is not defined

I'm adding security for my API keys with the Meteor package dotenv: https://github.com/okgrow/meteor-dotenv
as per instructions, I:
1. created a file named ".env" in my root
2. entered two keys in the style "THIS_KEY=BLAH12345" in the file
3. made a meteor call function returning process.env.THIS_KEY for the client side to use.
I'm getting Referenceerror: process.env is not defined. For just plain node there are a lot of answers out there, but not so for Meteor. Did I name my file incorrectly? Need to use a Meteor command to activate something?
I ran into this same problem, and have made it work by putting the
var secretThing = process.env.SECRET_THING
server side, inside the if (Meteor.isServer) and then passing the variable as a parameter to the method that needs to use the secret thing.
Meteor.call("apiCall", secretThing);
Then the receiving method looks like this:
apiCall: function (secretThing) {
console.log(secretThing);
}
DotEnv is designed to read environment variables from a .env file, normally located in the root of your NodeJS application.
DotEnv just makes the variables it finds in the .env file available with the rest of the host systems environment variables through process.env
The problem is, I don't believe meteor supports .env files. This is probably due to the age of the application. I personally believe they should make rectifying this a priority.
The only way you can use process.env in a meteor app is to set the variables you want to use on the host system. If you are using linux it would be something like
export DB_PASSWORD=12345
You should then be able to use process.env to read DB_PASSWORD when your application is running.
// You can only run process.env in server code
if (Meteor.isServer) {
const myDBPassword = process.env.DB_PASSWORD
}

Access a Meteor App's unique .id

I'm writing a Meteor package that needs to know the id of the app that includes it -- the value that is saved in the .meteor/.id file relative to the project directory.
How can I access the id safely in development AND in production?
This is doable from server-side code using NPM. I just tested the following on my local project and it works:
// server-side code
// FYI, Npm.require works in packages only. Use meteorhacks:npm to use
// in non-package code. In meteor shell you can just use `require`.
var fs = Npm.require('fs');
var path = Npm.require('path');
var idPath = path.join(process.env.PWD, '.meteor/.id');
var fileContent = fs.readFileSync(idPath);
var fileContentLines = fileContent.toString().split('\n');
// this will contain the ID
var theId = fileContentLines[fileContentLines.length - 2];
Now, keep in mind that in production, you don't have the .meteor directory. After running a grep for the id in the build folder, it seems to me like that ID is not stored in any file within the build. Therefore, you will need to create a build plugin which makes sure to make it accessible somewhere during the build process. I may not have looked hard enough, so I would definitely take a look at the source for the build tool and see what it does with that ID during build.
In Meteor 1.2.1, (and 1.3) the appId is accessible via the __meteor_runtime_config__.appId variable on the client and server in development mode. This is undocumented so we don't know if it will be available in future versions.
The .appId property of __meteor_runtime_config__ is NOT available:
In production mode (when Meteor.isProduction)
In test mode (when Meteor.isTest)
In app test mode (when Meteor.isAppTest)
How about using Meteor Settings file http://docs.meteor.com/#/full/meteor_settings? It should be the right way to do that, Otherwise you will have to use Node.js to access the file directly

Path variables not working on 0.6.5 e.g. METEOR_SETTINGS

i cannot get it working after i updated to 0.6.5.
I created a new meteor project.
I have a start.sh script that looks like this.
export METEOR_SETTINGS=$(cat ./settings.json)
meteor
settings.json:
{
"public":{
"bla":"blup"
}
}
Meteor.settings on the client is undefined. It works if i add the settings json file via "--settings", but unfortunately this is not what i need.
The PORT environment variable or NODE_ENV also does not work for me.
Adding some random stuff like "export MY_ENV_VAR=foo" however works.
Am i missing s.th.? It all worked well before. I would really appreciate your help.
Thx!
(also created an issue: https://github.com/meteor/meteor/issues/1381)
If you are trying to test your meteor app locally (dev mode) or you want to deploy your app to the Meteor hosting, then just pass the file path as settings param:
meteor --settings settings.json
In case of running from bundle on your own server, then you need the environment variable.
Docs.

How to create manage/server side commands?

Is there a way in Meteor, to add your own commands to the meteor command for the given project? So that on the server side you could have some commands similar to Django's manage commands. Like command for importing/updating data, maybe cron jobs, things like that? Thing is, I would like commands to have access to all the libraries and environment Meteor provides, especially so that I am sure that data stored in the database is compatible with Meteor.
At the moment this isn't directly possible without an edit of meteor's source. If you're using meteorite you can have a localized meteor version which won't affect the rest of your meteor apps.
You might have to add a custom function over at /tools/meteor.js in this forked/modified meteor.
with:
Commands.push({
name: "yourcustomcommand",
help: "..",
func: function (argv) {
//Custom stuff
});

Resources