Convert node module's exported functions' into JSON objects? - node.js

it is my first question so I hope I'll write it well, any suggestion is well accepted. This is a design question.
I'm using the create-electron-app-typescript boilerplate. I use uniforms & JSON schemas for user input, and I'm new to all of these languages/tools.
I'm designing a tool that aims to create a simple, general graphical interface for modules that can expose (export) certain functionalities.
e.g.:
module.exports = {
function sendMoney(account?, amount),
function foo(something)
}
I wish I could translate each function in a schema like this:
{
"title": "sendMoney",
"type": "object",
"properties": {
"account": {
"type":"string"
},
"amount": {
"type":"int"
}
},
"required": ["amount"]
}
in order to easily translate it instantly into a form as I do now using Uniforms/React.
The goal is to let the user implicitly create a high level "script" which is the ordered and sequential execution of these functions, that will be interpreted in a second moment.
[EDITED]

Related

Generate itemId when batchUpdating with Forms API

Please what are the constraints in generating an itemId. I generate unique itemId for each item in the form, but the API keeps telling me invalid ID.
https://developers.google.com/forms/api/reference/rest/v1/forms#Item
Please I need help with this
{
"includeFormInResponse": false,
"requests": [
{
"createItem": {
"item": {
"itemId": "4e637fjc",
"description": "First Name",
"questionItem": {
"question": {
"textQuestion": {
"paragraph": false
},
"required": true
}
}
},
"location": {
"index": 0
}
}
},
{
"createItem": {
"item": {
"itemId": "njyf3izr",
"description": "Middle Name",
"questionItem": {
"question": {
"textQuestion": {
"paragraph": false
},
"required": true
}
}
},
"location": {
"index": 1
}
}
},
}
]
When I had tested Google Forms API before, unless I'm mistaken, I had thought that the rule of item ID might be required to be 00000000 to 7fffffff as the hex value. By the way, for example, 0 is used as 00000000.
When I saw your showing request body, you are trying to use 4e637fjc and njyf3izr as the item ID. In the case of these values, the values are not hex values. I thought that by this, an error like Invalid ID occurred.
But, I think that actually, this is not published in the official document. So, I would like to tell this.
Added:
About your following reply,
Do you mean something like this, with Javascript. crypto.randomBytes(256).toString('hex').slice(0, 8)
From your tag, when you want to use Google Apps Script or Node.js, how about the following sample script? Unfortunately, Google Apps Script cannot directly use "crypto". So, I proposed the following sample script.
Sample script:
const res = Math.floor(Math.random() * parseInt("7FFFFFFF", 16)).toString(16).padStart(8, "0");
console.log(res);
In this sample script, the values of 00000000 to 7fffffff are randomly returned.
Missing documentation
I am afraid that since the Forms API is very new there is no documentation about the specific format the ID should have.
I have done a couple of tests with the API and the only thing I was able to figure out is that the ID needs an 8-character-long string to work, otherwise it would not work or would fill out the blank spaces with zeros.
When doing the testing I was also able to find out that sometimes the API would take a specific pattern of letters and numbers, but when changing the numbers and letters it stops working for no reason.
This seems like missing clarification from the documentation, and I would strongly recommend sending feedback about this problem on the API method page. You can do so by clicking the following option at the top right corner of the documentation:
Google tends to check that feedback a lot when talking about missing information. In addition to all that you can also fill out a report in Google's issue tracker so that they investigate the inconsistencies when using the batchUpdate method to update the ID.
References:
Forms Item
Method: forms.batchUpdate

Sequelize "raw = true" changes json model attribute name with dot

I have Content model and it has many sub ContentImage item, like this;
const content = await db.Content.findOne({
where: {
permalink: req.params.permalink
},
include: [{
model: db.ContentImages
}]
raw: true
});
As you know raw:true covert SequelizeInstance to Object model. I have some problem in this point.
If I use raw:true, json model show me like this;
{
"id": 4706,
"name": "Content Title",
"content": "Content detail",
"t_content_images.id": 7633,
"t_content_images.content_id": 4706,
"t_content_images.image": "content-image-1.jpg",
"t_content_images.order_no": 1
}
Because of expressjs, I need like this model instead of SequelizeInstance;
{
"id": 4706,
"name": "Content Title",
"content": "Content detail",
"t_content_images": {
"id": 7633,
"content_id": 4706,
"image": "content-image-1.jpg",
"order_no": 1
}
}
Another problem, I have multiple content image and if I use like above first sample, it returns me just first content image.
You are thinking about it a bit backwards - when you use raw: true it doesn't convert it from a JSON object to a Model Instance.
If you think of how SQL results are structured, they always come back flat. This means that for joins where you have one base record linked to multiple children (Content -< ContentImages in this case) then the SQL results will repeat the info for the base record for each of the children. Sequelize will parse this into a JSON object, which is what you are seeing in the first example in your question. If you leave out raw: true then it will take it a step further and parse it into an instance of your model. You can then call Model.toJSON() to get a JSON representation of the parsed object.
Given the above, if you are fetching lots of children then it can be more efficient to get the data into two queries instead of one so you don't have to send the repeating data to the client.

Is it possible that "Server-side fan-out" can process with Cloud Functions for Firebase?

Recently Cloud Functions has released on Firebase.
I'm developing social network service via Firebase and using "Fan-out" process for data consistency as explained on here.
Since "Client-side fan-out" is a bit inefficient for large data. Can we resolve this on Server-side with Cloud Functions?
If possible, can you guys give me a workaround to do this. Or if there is sample code with it please reference me.
For examples, if new data is inserted on posts node, how can we Fan-out this data on timeline node for each following user?
Thank you.
{
"posts": {
"-K-zOrtjiCGe7tgRk8DG": {
"text": "I love emojis!",
"uid": "user1"
}
},
"timeline": {
"user2": {
"-K-zOrtjiCGe7tgRk8DG": {
"text": "I love emojis!",
"uid": "user1"
}
},
"user3": {
"-K-zOrtjiCGe7tgRk8DG": {
"text": "I love emojis!",
"uid": "user1"
}
}
},
"followers": {
"user1": {
"user2": true,
"user3": true
}
}
}
You can definitely write a database trigger with Cloud Functions for Firebase to do this. The trigger function can run whenever something under /posts changes, get a hold of the new data, and write it to the other places in the database where it should be duplicated. This removes the responsibility of all your clients to do the same work, and allows you to tighten up your security rules on the duplicated data.

How to populate a non related field mongoose

Document Role =
{ "_id" = "12345",
Name = "Developer"
},
{ "_id" = "67890",
Name = "Manager"
}
Document Employee =
{ "_id" = "00000",
"Name"= "Jack",
"Roles"= [{_id:"12345"},{_id:"67890"}]
}
I want to select one Role and list all the users having the same role
How to do that?
I want to get some thing like.
{ "_id" = "12345",
Name = "Developer"
Employees = [{"_id":"00000"}]
}
Is it possible to use populate to achieve this?
Mongoose .populate() and other methods you might find are not "join magic" for MongoDB. What they in fact all do is execute "additional" query(ies) operations on the database and "merge" the results "under the hood" for your as opposed to you doing the work yourself.
So your best option as long as you can deal with it is to use "embedding" which keeps the "related" information in the document for which you are "pairing" it to, such as for "Roles":
{
"_id": "0000",
"name": "Developer",
"employees": [{ "_id": "12345", "name": "Jack" }]
}
Which is simple, but of course comes at it's own cost and dealing with the "embedded" entries and how you use it according to "updating" or "reading" as is appropriate. It's a single "read" operation, but "updates" may be more costly due to the need to update the embedded information in multiple places, and multiple documents.
If you can "live" with "referencing" and the cost it incurs then you can always do this:
var rolesSchema = Schema({
"name": String,
"emloyees": [{ "type": Schema.Types.ObjectId, "ref": "Employee" }]
});
var employeesSchema = Schema({
"name": String,
"roles": [{ "type": Schema.Types.ObjectId, "ref": "Role" }]
});
var Role = mongoose.model('Role',rolesSchema);
var Employee = mongoose.model('Employee',employeeSchema);
Role.find({ "_id": "12345"}).populate("employees").exec(function(err,docs) {
// populated "joined" results in here
})
What this does behind the scenes is effectively (basic JavaScript representation and "at best") :
var roles = db.role.find({ "_id": "12345" }).map(function(doc) {
doc.employees = doc.employees.map(function(employee) {
return db.employees.find({ "_id": { "$in": doc.employees } }).toArray();
})
})
Mongoose works on the concept of using the "schema" definition to "know" which collection to execute the "other query" on and then return the "joined" results to you. But it is not a single query but multiple hits to the database.
Other schemes might "keep" the referenced collection information in the document itself, as opposed to relying on the "model code" to get that information. But the same principle applies where you need to make another call to the database and perform some type of "merge" in the API provided.
So it all falls down to your choice. Either you "embed" the data and live with that cost, or you "reference" the data and live with the network "cost" that is associated with multiple database hits.
The key point here is "nothing is free", and not even the way that SQL RDBMS perform "joins" which also has a "cost" of it's own and is a lot of the reasoning why NoSQL solutions like MongoDB do it this way and "do not support joins" in a native fashion for the "cost" involved in distributed data systems.
The main lesson here is to "do what suits you and your application", and not just choose the "coolest thing right now", but basically expect what you get from choosing different storage solutions. They all have their own purposes. Horses for Courses as the saying goes.

How could I determine all possible keys of a CouchDB database?

I am creating one application where for every product I have one database and I will create different document based on date. The keys in documents could be different and depend upon user, what he provides. Assumption is user will keep giving same key for tracking with changed value over time. In the end, I need to know all possible keys before creating automatic views on them.
Example:
If I had DB, say, test. It contains, say, two documents,
1. {
"_id":"1",
"_rev":"1-"
"type": "Note",
"content": "Hello World!"
}
2. {
"_id":"2",
"_rev":"1-"
"type": "Note",
"content": "Beyond Hello World!",
"extra":"Boom"
}
Then I want to list all keys in this DB. So, answer should be _id,_rev,type,content and extra.
These keys are dynamic and depend upon users. So, I couldn't assume that I knew them in advance.
I have never used stackoverflow before, I saw your question when trying to solve this problem myself so I have signed up. I think this solves your problem:
create a view where "views" includes this:
{
"keys": {
"map": "function(doc) { for (var thing in doc) { emit(thing,1); } }",
"reduce": "function(key,values) { return sum(values); }"
}
}
then query on that view with group=true e.g.:
http://localhost:5984/mydb/_design/myview/_view/keys?group=true
you should get back a list of all the keys in your database and a count of how often the occur.
does this help?

Resources