Migrating main.js to Parse Server - node.js

I need help migrating my parse server and was directed here by the parse support page.
I have finished the database migration to an mLab database and have the parse server example running in heroku.
My project runs perfectly at retrieving my current data with the default parse server example main.js file, but I would like to still run ParseServer jobs from the client like in this iOS example so I would like to use my own main.js file.
[PFCloud callFunction:#"publishCard" withParameters:#{
#"cardID" : card.cardPF.objectId,
} error:&error];
When I try to run my project with the following file as main.js (I've renamed it newmainjs just for visibility), it doesn't let me login with parse at all anymore from my iOS Client--so it seems to be triggering errors and I have no idea how to debug it as it's not covered in the migration tutorial.
https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js
I am very amateur at backend/node so I would really appreciate some support, as I relied on Parse for a lot of things before.

take a look at: https://parse.com/migration
section 3 "cloud code".
You need to change any use of:
Parse.Cloud.useMasterKey()
which you use:
here:
https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js#L162
and here: https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js#L633
instead of using useMasterKey(), you need to pass 'useMasterKey: true' to queries and saves.
Here are a few examples from your code:
userQuery.find({
useMasterKey: true, // <-- note the addition here
success: function(results) {
console.log(results.count);
....
And:
}).then(function(saveObjects)
{
Parse.Object.saveAll(updatedUserObjects, {
useMasterKey: true, // <--- here
success: function(list) {
//assumes all are saved
response.success("user EloRatings Saved Successfully");
},
.....
And:
Parse.Cloud.define("giveSellerGold", function(request, response) {
Parse.Cloud.useMasterKey();
var user = new Parse.User();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", request.params.sellerID);
query.first({
useMasterKey: true, // <--- here
success: function(object) {
object.increment("gold", request.params.sellerGold);
object.save(null, { useMasterKey: true }); // <-- note how save is done.
response.success("Successfully saved gold");
},
error: function(error) {
response.error("update failed");
}
});
});
so just make sure that all the queries (that need it) are passing 'useMasterKey' in the options and that ought do it! Good luck.

Related

Can't use Worker-Loader with Vuejs and Webpack

I am trying to get web workers up and running with Vue cli3 and I'm having trouble getting it to work.
I want to use the following package, worker-loader (and not vue-worker), as it looks well maintained and with more contributions.
Following their tutorial I attempted to modify webpack using the vue cli as follows:
module.exports = {
chainWebpack: config => {
config.module
.rule('worker-loader')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end()
}
}
which I hope should match their
{
module: {
rules: [
{
test: /\.worker\.js$/,
use: { loader: 'worker-loader' }
}
]
}
}
which can be read here (https://github.com/webpack-contrib/worker-loader). I tried to follow the documentation for vue cli3 as best I could (found here: https://cli.vuejs.org/guide/webpack.html#simple-configuration).
My component is pretty simple:
import Worker from 'worker-loader!./../../sharedComponents/equations/recurringTimeComposer.js';
<...>
watch:{
recurringPaymentReturnObj: function(newVal, oldVal){
const myWorker = new Worker;
myWorker.postMessage({ hellothere: 'sailor' });
myWorker.onmessage = (e) => {
console.log('value of e from message return', e.data);
}
}
<...>
and in my ./../../sharedComponents/equations/recurringTimeComposer.js file I have:
onmessage = function(e) {
console.log('Message received from main script: ', e.data);
// var workerResult = 'Result: ' + e.data;
// console.log('Posting message back to main script');
postMessage('hello back handsome');
close();
}
I keep getting the error message:
ReferenceError: window is not defined a162426ab2892af040c5.worker.js:2:15
After some googling I came across this post: https://github.com/webpack/webpack/issues/6642, which suggests that the best way to fix this is to add the following to webpack:
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
publicPath: 'http://localhost:3000',
globalObject: 'this'
},
After modifying my vue.config.js file I have:
module.exports = {
chainWebpack: config => {
config.module
.rule('worker-loader')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end()
config
.output
.path(path.join(__dirname, 'dist'))
.filename('bundle.js')
.publicPath('http://localhost:8080')
.globalObject('this')
}
}
...but still I am getting the window is not defined error.
Does anyone know what is going wrong? It seems to be a weird error in webpack.
Thanks!
EDIT: oh yeah, here is the MDN page for webworker as well: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers.
Being new to Javascript I kept coming back to this issue when trying to use web workers with VueJS. I never managed to make it work with vue-worker or worker-loader.
It is now 2020 and Google has released worker-plugin.
To use it create a module my-worker with two files index.js and worker.js.
index.js creates the module:
const worker = new Worker('./worker.js', { type: 'module' });
const send = message => worker.postMessage({
message
})
export default {
worker,
send
}
worker.js contains the logic:
import _ from 'lodash'
addEventListener("message", async event => {
let arrayToReverse = event.data.message.array
let reversedArray = _.reverse(arrayToReverse)
// Send the reversed array
postMessage(reversedArray)
});
You will also need to update your vue.config.js to use the WorkerPlugin:
const WorkerPlugin = require('worker-plugin')
module.exports = {
configureWebpack: {
output: {
globalObject: "this"
},
plugins: [
new WorkerPlugin()
]
}
};
Now you can use you worker in your components:
Import it with import worker from '#/my-worker'.
Setup a listener in the mounted() lifecycle hook with worker.worker.onmessage = event => { // do something when receiving postMessage }
Start the worker with worker.send(payload).
I set up a starter code on github. I still haven't managed to make HMR work though...
This works for me (note the first line):
config.module.rule('js').exclude.add(/\.worker\.js$/)
config.module
.rule('worker-loader')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
The first line excludes worker.js files, so two loaders wouldn't fight over the same js file
is this what you need ? Vue issue with worker-loader
Updating from the classic vue & webpack config, I found out that to make this one work, I needed to deactivate parallelization.
// vue.config.js
module.exports = {
parallel: false,
chainWebpack: (config) => {
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end();
}
};
I tried add web worker to a vue-cli4 project, and here is what I found:
using worker-loader and make configs in chainWebpack:
HMR works fine, but sourcemap broke, it show babel transformed code.
using worker-plugin as #braincoke mentioned:
HMR broke, but sourcemap works fined. and eslint broke while suggested disable all worker js file eslint instead.
Finally, My solution is tossing vue-cli away, and embrace vite.It support worker natively, and all just go fine now. (I think upgrade webpack to v5 can solve this, but i never tried.)

Is DB a reserved word in Node.js

I am building some tests with mocha and chai(expect).
Keeping it simple as I am learning about testing methodology as I go along.
I have a mysql db layer in a config file.
Testing the db parameters, I ran into a weird issue.
These db parameters test fine:
host= 'localhost',
user='foo',
password='bar',
The tests:
var expect = require('chai').expect;
var db = require('../db/config.ini');
describe('Database Access', function() {
it('HOST parameter should be a string', function() {
expect(host).to.be.a('string');
});
it('USER parameter should be a string', function() {
expect(user).to.be.a('string');
});
it('PASSWORD parameter should be a string', function() {
expect(password).to.be.a('string');
});
it('DB parameter should be a string', function() {
expect(db).to.be.a('string');
});
it('HOST parameter should equal localhost', function() {
expect(host).to.equal('localhost');
});
it('USER parameter should equal foo', function() {
expect(user).to.equal('foo');
});
it('PASSWORD parameter should equal bar', function() {
expect(password).to.equal('bar');
});
it('DB parameter should equal thatone', function() {
expect(context).to.equal('thatone');
});
});
When I add the database to choose,
db='thatone';
The test fails the parameter because it reads it as an object.
1) Database Access DB parameter should be a string:
AssertionError: expected {} to be a string
at Context.<anonymous> (test/db_tests.js:21:20)
If I change the variable name to "context" the test passes as expected.
I'm wondering if there is something obvious I am missing about using "db" as a variable.
UPDATE
Really stupid, novice level mistake.
So focused on learning testing methodology I didn't realize I had created the
'db' var as a require to the 'ini' and then referenced it later as though it was unique.
Really dumb. Rushing through this recklessly to get to a destination, and failing to follow some good methodology.
The result of executing this is not a string:
var db = require('../db/config.ini');
It seems you are trying to get a file in some INI dialect to be meaningfully interpreted by Node. Node does not support this by default. If you do not get an error while loading it, the most likely reason is that the text you have in there happens to also be valid JavaScript but since INI files do not contain proper code to export something (i.e. the file does not contain exports.db = "something" or module.exports = { ... } or something similar), then the module has the value {}.
You need to add one of the multiple npm packages that will automatically interpret an INI file and provide a meaningful value. I cannot recommend one as I don't use INI files in my software but you can search npm for a package that will perform the translation for you.

Understanding ExpressJS application start-up

I am struggling with how application start-up works in Express. I am going to explain my use-case:
I have a configuration-Manager module which is used by all other application modules to load required configuration. I am setting configuration in app.listen:
app.listen(9000, function () {
try
{
config_manager.setSiteConfig();
console.log('settings..!!!')
}
catch(err)
{
console.log(err.stack);
}
});
In another module of the same application I call the Configuration-Manager function to load config, but it returns empty. Code is something like this:
var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {}
I am running the application using node app.js. The empty object gets printed first then ('settings..!!!'). Does Express compile the script before calling app.listen()? How do I make sure that my configuration is set before compilation/loading other files?
Express indeed first processes all statements in a file, basically anything that isn't in a function on startup.
In your case var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {} is executed before your app.listen because you are requering the config before the app.listen.
You're best off processing your configuration right after the first time it is required (if app.js is your main file, this means the first time it comes across a require statement pointing to configuration-manager in any file).
This should make your code work:
var config_manager = require('configuration-manager');
try {
config_manager.setSiteConfig();
} catch(err) {
console.log(err.stack);
}
console.log(config_manager.loadConfig()); // returns empty object {}
and then
app.listen(9000, function () {
console.log('settings..!!!', config_manager.loadConfig()) // Should correctly print your config
});
If this doesn't work the problem does not lay in the order of execution.

Gulp is not updating my static generated pages with Assemble

I have a working Modular Gulpfile which is building my static pages with assemble. So far so good. When i run a watch job and change my data in a Json file the watcher is running assemble again, building the pages without the new data. Handlebars partials and all other things are working exept for the data files. When i quit my watch task and run the whole assemble task again, the data is updated, so the assemble task works i think.
This is my assemble task.
module.exports = function(gulp, plugins, config, assemble, browserSync) {
var error = require("./error.js");
var clean = require("./clean-html.js");
//var production = require("./distribution.js");
var app = assemble();
gulp.task('load', function() {
app.partials(config.source.assembleSrc.partials);
app.layouts(config.source.assembleSrc.layouts);
app.data(config.source.assembleSrc.data);
});
gulp.task('assemble', ['load'], function() {
return app.src(config.source.assembleSrc.pages)
.pipe(plugins.plumber({
errorHandler: error
})) //Added proper error handling
.pipe(app.renderFile())
.pipe(plugins.rename(function(path) {
path.extname = ".html" // Rename to HTML
}))
.pipe(plugins.if(production, gulp.dest(config.dist.html), gulp.dest(config.temp.html)))
.pipe(browserSync.reload({
stream: true
})); // Browser reload
});
};
Thanx in advance!

Gulp, livereload, jade

Need help.
I use gulp-conect and it livereload method. But if I build a few template in time, get a lot of page refresh. Is any solution, I want to build few templates with single page refresh?
So, I reproduce the problem you have and came accross this working solution.
First, lets check gulp plugins you need:
gulp-jade
gulp-livereload
optional: gulp-load-plugins
In case you need some of them go to:
http://gulpjs.com/plugins/
Search for them and install them.
Strategy: I created a gulp task called live that will check your *.jade files, and as you are working on a certain file & saving it, gulp will compile it into html and refresh the browser.
In order to accomplish that, we define a function called compileAndRefresh that will take the file returned by the watcher. It will compile that file into html and the refesh the browser (test with livereload plugin for chrome).
Notes:
I always use gulp-load-plugin to load plugins, so thats whay I use plugins.jad and plugins.livereload.
This will only compile files that are saved and while you have the task live exucting on the command line. Will not compile other files that are not in use. In order to accomplish that, you need to define a task that compiles all files, not only the ones that have been changed.
Assume .jade files in /jade and html output to /html
So, here is the gulpfile.js:
var gulp = require('gulp'),
gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins();
gulp.task('webserver', function() {
gulp.src('./html')
.pipe(plugins.webserver({
livereload: true
}));
gulp.watch('./jade/*.jade', function(event) {
compileAndRefresh(event.path);
});
});
function compileAndRefresh(file) {
gulp.src(file)
.pipe(plugins.jade({
}))
.pipe(gulp.dest('./html'))
}
Post edit notes:
Removed liveReload call from compileAndRefresh (webserver will do that).
Use gulp-server plugin insted of gulp-connect, as they suggest on their repository: "New plugin based on connect 3 using the gulp.src() API. Written in plain javascript. https://github.com/schickling/gulp-webserver"
Something you can do is to watch only files that changes, and then apply a function only to those files that have been changed, something like this:
gulp.task('live', function() {
gulp.watch('templates/folder', function(event) {
refresh_templates(event.path);
});
});
function refresh_templates(file) {
return
gulp.src(file)
.pipe(plugins.embedlr())
.pipe(plugins.livereload());
}
PS: this is not a working example, and I dont know if you are using embedlr, but the point, is that you can watch, and use a callback to call another function with the files that are changing, and the manipulate only those files. Also, I supposed that your goal is to refresh the templates for your browser, but you manipulate as you like, save them on dest or do whatever you want.
Key point here is to show how to manipulate file that changes: callback of watch + custom function.
var jadeTask = function(path) {
path = path || loc.jade + '/*.jade';
if (/source/.test(path)) {
path = loc.jade + '/**/*.jade';
}
return gulp.src(path)
.pipe(changed(loc.markup, {extension: '.html'}))
.pipe(jade({
locals : json_array,
pretty : true
}))
.pipe(gulp.dest(loc.markup))
.pipe(connect.reload());
}
First install required plugins
gulp
express
gulp-jade
connect-livereload
tiny-lr
connect
then write the code
var gulp = require('gulp');
var express = require('express');
var path = require('path');
var connect = require("connect");
var jade = require('gulp-jade');
var app = express();
gulp.task('express', function() {
app.use(require('connect-livereload')({port: 8002}));
app.use(express.static(path.join(__dirname, '/dist')));
app.listen(8000);
});
var tinylr;
gulp.task('livereload', function() {
tinylr = require('tiny-lr')();
tinylr.listen(8002);
});
function notifyLiveReload(event) {
var fileName = require('path').relative(__dirname, event.path);
tinylr.changed({
body: {
files: [fileName]
}
});
}
gulp.task('jade', function(){
gulp.src('src/*.jade')
.pipe(jade())
.pipe(gulp.dest('dist'))
});
gulp.task('watch', function() {
gulp.watch('dist/*.html', notifyLiveReload);
gulp.watch('src/*.jade', ['jade']);
});
gulp.task('default', ['livereload', 'express', 'watch', 'jade'], function() {
});
find the example here at GitHub

Resources