acorn AST query template literal element - javascript

I'm trying to query the following:
const t = 'template';
const s = `I'm a ${t}`;
Acorn parses the template literal portion as:
{
"type": "TemplateLiteral",
"start": 32,
"end": 53,
"expressions": [
{
"type": "Identifier",
"start": 50,
"end": 51,
"name": "t"
}
],
"quasis": [
{
"type": "TemplateElement",
"start": 33,
"end": 48,
"value": {
"raw": "I'm a ",
"cooked": "I'm a "
},
"tail": false
},
{
"type": "TemplateElement",
"start": 52,
"end": 52,
"value": {
"raw": "",
"cooked": ""
},
"tail": true
}
]
}
Let's say I wanted to query this by the raw or cooked keys of the value key of the TemplateElement. Since the nested value item doesn't have a type I'm a bit lost as to how to target that node by those attributes. How would I write that query using astq?

Related

filter array of object and add extra filed for duplicate value?

i have a array of object. i want to filter by two key and if there is any duplicate item need to add extra key including details
for example
[
{
"start": 0,
"end": 38,
"content": "announcing improvements to the GitHub "
},
{
"uuid": "6f08b9df-7b07-4da9-bbe0-8c93d5d0a19b",
"start": 51,
"end": 59,
"entity_type": "class1",
"content": "Workflow"
},
{
"uuid": "21dffe1c-0f8c-4c13-8bee-6185fb15cbd8",
"start": 51,
"end": 59,
"entity_type": "class2",
"content": "Workflow"
},
{
"start": 59,
"end": 101,
"content": "” experience. Now, when you want to create"
}
]
and expected output is
let excepted = [
{
"start": 0,
"end": 38,
"content": "announcing improvements to the GitHub "
},
{
"uuid": ["6f08b9df-7b07-4da9-bbe0-8c93d5d0a19b","21dffe1c-0f8c-4c13-8bee-6185fb15cbd8"],
"start": 51,
"end": 59,
"isDuplicate":true,
"labels":["class2","class1"],
"content": "Workflow"
},
{
"start_offset": 59,
"end": 101,
"content": "” experience. Now, when you want to create"
}
]
in above example you can see for key start 51 and end 59 have two duplicate entry in output i want to aggregate both like in output labels
Just a little bit different result, instead "labels":["class2","class1"] it's "entity_type":["class2","class1"]
const arr = [{"start": 0,"end": 38,"content": "announcing improvements to the GitHub "},{"uuid": "6f08b9df-7b07-4da9-bbe0-8c93d5d0a19b","start": 51,"end": 59,"entity_type": "class1","content": "Workflow"},{"uuid": "21dffe1c-0f8c-4c13-8bee-6185fb15cbd8","start": 51,"end": 59,"entity_type": "class2","content": "Workflow"},{"start": 59,"end": 101,"content": "” experience. Now, when you want to create"}]
const reduced = arr.reduce((acc, obj) => {
const hash = `${obj.start}-${obj.end}`;
if (acc[hash]) {
acc[hash] = {
...acc[hash],
isDuplicate: true,
uuid: Array.isArray(acc[hash].uuid)
? [obj.uuid]
: [acc[hash].uuid, obj.uuid],
entity_type: Array.isArray(acc[hash].entity_type)
? [obj.entity_type]
: [acc[hash].entity_type, obj.entity_type],
};
} else {
acc[hash] = { ...obj };
}
return acc;
}, {});
const result = Object.values(reduced);
console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}

Get the value of an object in Javascript [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
How can I access object properties containing special characters?
(2 answers)
Closed 2 years ago.
I was using wit.ai's JSON to get the data and recently they changed the structure. This is how it looks
"entities": {
"paraName:paraName": [
{
"id": "1266de86-97af-434b-95ee-f87ff58c935a",
"name": "paraName",
"role": "paraName",
"start": 30,
"end": 34,
"body": "data",
"confidence": 0.549,
"entities": [
],
"suggested": true,
"value": "data",
"type": "value"
},
{
"id": "1266de86-97af-434b-95ee-f87ff58c935a",
"name": "paraName",
"role": "paraName",
"start": 39,
"end": 45,
"body": "height",
"confidence": 0.8922,
"entities": [
],
"value": "height",
"type": "value"
}
]
}
This is how I am trying to get the value of those parameters (i.e. data, and height)
let data = response.entities;
let paraMeter = data.paraName.map(function(res){
return res['value'];
})
keyValues = paraMeter.join().split(',');
but I am getting Cannot read property 'map' of undefined error. Anyone knows what's wrong here?
Thank you
You can refer the key like shown in this snippet:
let paraMeter = data["paraName:paraName"].map(function(ref){
More details here :
Properties of JavaScript objects can also be accessed or set using a
bracket notation (for more details see property accessors). Objects
are sometimes called associative arrays, since each property is
associated with a string value that can be used to access it.
let response = {"entities": {
"paraName:paraName": [
{
"id": "1266de86-97af-434b-95ee-f87ff58c935a",
"name": "paraName",
"role": "paraName",
"start": 30,
"end": 34,
"body": "data",
"confidence": 0.549,
"entities": [
],
"suggested": true,
"value": "data",
"type": "value"
},
{
"id": "1266de86-97af-434b-95ee-f87ff58c935a",
"name": "paraName",
"role": "paraName",
"start": 39,
"end": 45,
"body": "height",
"confidence": 0.8922,
"entities": [
],
"value": "height",
"type": "value"
}
]}
};
let data = response.entities;
let paraMeter = data["paraName:paraName"].map(function(ref){
return ref['value'];
})
keyValues = paraMeter.join().split(',');
console.log(keyValues);

How to Restructure/Translate Json objects to satisfy any schema?

I have a (long) json schema and I already validate the json objects in my code based on that schema.
My problem/use-case is to translate/restructure an incoming json object to a new json object that satisfies my schema.
I realized however, that it isn't that easy to do, especially if you look for an "adaptive" solution.
Adaptive meaning that the code doesn't care about changes of the schema or the incoming object.
So my first approach was to create a class that contains a mapping of the incoming object to a valid object.
This means however that I have to write this map by hand and update it if I change the schema.
So is there a solution where I can insert any schema, any non-valid (based on schema) json object and get a valid object out?
Or at-least a way to generate a valid json object template, where you can insert the data of the incoming invalid json object?
This way I could at least be independent from schema changes.
PS: I tried to solve this problem in an abstract way, but if needed I can provide schema and the invalid object.
PPS: My environment is node.js.
Edit: E.g.:
Schema
{
...//other Schema stuff (using draft-07)
"tokens": {
"$id": "/token",
"title": "Token",
"description": "A representation of a word in a Message with all the nlp Analysis results and infos",
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/tokens/definitions/token"
},
"token": {
"$id": "#token",
"type": "object",
"required": [
"id",
"text"
],
"properties": {
"id": {
"description": "global (level:conversation) unique identifier to identify a token (cumulative)",
"type": "number",
"exclusiveMinimum": 0,
"uniqueItems": true
},
"isText": {
"description": "Describes if the token is a real semantic word or a whitespace or similar",
"type": "boolean"
},
"text": {
"description": "the actual content of the token",
"type": "string",
"pattern": "^(.+)$"
},
"word_index": {
"description": "Index of a word in a text",
"type": "number",
"exclusiveMinimum": 0,
"uniqueItems": true
},
"punctuation": {
"description": "The punctuation that needs to be rendered before/after that token. TODO: finish it",
"type": "string"
},
"characterOffsetBegin": {
"type": "integer",
"description": "The inclusive character index in the sentence where this token begins"
},
"characterOffsetEnd": {
"type": "integer",
"description": "The exclusive character index in the sentence where this token ends"
},
"lemma": {
"type": "string",
"pattern": "^(.+)$"
},
"pos": {
"type": "string",
"description": "part of speech tag",
"pattern": "^(.+)$"
},
}
},
"text_label": {
//This is where it gets difficult
"description": "Label of the text for the frontend. ",
"type": "object",
"required": [
"name",
"begin",
"end"
],
"additionalProperties": false,
"properties": {
"name": {
"description": "Name of the label",
"type": "string"
},
"begin": {
"description": "Token index where the label starts",
"type": "number"
},
"end": {
"description": "Token indes where the label ends",
"type": "number"
}
}
}
}
}
Object to translate:
{
"text": "Hello, my name is Somebody. ",
"sentences": [
{
"index": 0,
"tokens": [
{
"index": 1,
"word": "Hello",
"originalText": "Hello",
"characterOffsetBegin": 0,
"characterOffsetEnd": 5,
"before": "",
"after": "",
"pos": "UH",
"lemma": "hello"
},
{
"index": 2,
"word": ",",
"originalText": ",",
"characterOffsetBegin": 5,
"characterOffsetEnd": 6,
"before": "",
"after": " ",
"pos": ",",
"lemma": ","
},
{
"index": 3,
"word": "my",
"originalText": "my",
"characterOffsetBegin": 7,
"characterOffsetEnd": 9,
"before": " ",
"after": " ",
"pos": "PRP$",
"lemma": "my"
},
{
"index": 4,
"word": "name",
"originalText": "name",
"characterOffsetBegin": 10,
"characterOffsetEnd": 14,
"before": " ",
"after": " ",
"pos": "NN",
"lemma": "name"
},
{
"index": 5,
"word": "is",
"originalText": "is",
"characterOffsetBegin": 15,
"characterOffsetEnd": 17,
"before": " ",
"after": " ",
"pos": "VBZ",
"lemma": "be"
},
{
"index": 6,
"word": "Somebody",
"originalText": "Somebody",
"characterOffsetBegin": 18,
"characterOffsetEnd": 26,
"before": " ",
"after": "",
"pos": "NN",
"lemma": "somebody"
},
{
"index": 7,
"word": ".",
"originalText": ".",
"characterOffsetBegin": 26,
"characterOffsetEnd": 27,
"before": "",
"after": "",
"pos": ".",
"lemma": "."
}
],
"basicDependencies": []
}
]
}
Note: that this is corenlp analysis result that can change based on the annotator used.
Edit2: adding example of a correct object:
{ ...other parts of the object
tokens:[
{ id:1, text: 'Hello', isText: true, word_index: 0, characterOffsetBegin:0, characterOffsetEnd: 5, lemma: 'hello', pos:'UH', ...},
{...},
{...}
],
text_label:{
name: 'joy', begin: 0, end: 3
}
}
or another text_label:
text_label:{
name: 'PERSON', begin: 4, end: 5
}
Edit: Difference:
As you can see, some changes a suttle like index->word_index, some are additional information like id, but some need a bit more like the text_label.
corenlp. It could also happen that I need to unify 2 objects together. which is the case of the 'anger' text_label but isnt with the PERSON text_label.
So Im looking for some kind of json Object/Schema manager where translations, validations get easy and dont need hard coded mappings or the generation of that mappings is easy.

Displaying a local image in Node-RED dashboard using http endpoints

I need to display an image on Node-RED dashboard using http end points.
I have done the followings:
Kept the image in /home/pi/Pictures.
Edited httpStatic: '/home/pi/Pictures', in setting.js file.
Tried using slash "/" before image name in src in html image tag and
without "/" but nothing works.
Here is my flow for reference:
[
{
"id": "7b08a202.a1670c",
"type": "http in",
"z": "e5e5e9b.2a8cc18",
"name": "",
"url": "/display-image",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 112,
"y": 73,
"wires": [
[
"35ca7d97.da9dd2"
]
]
},
{
"id": "f8cf60ed.74b87",
"type": "http response",
"z": "e5e5e9b.2a8cc18",
"name": "",
"statusCode": "",
"headers": {
},
"x": 458,
"y": 70,
"wires": [
]
},
{
"id": "35ca7d97.da9dd2",
"type": "template",
"z": "e5e5e9b.2a8cc18",
"name": "SLD View",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "<!DOCTYPE html>\n<html>\n <body>\n <img src=\"Barsu_SLD.png\" alt=\"Overview\" width=1000px; height=800px>\n \n </body>\n</html>",
"output": "str",
"x": 310,
"y": 136,
"wires": [
[
"f8cf60ed.74b87"
]
]
},
{
"id": "2beda89c.ca2b98",
"type": "ui_template",
"z": "e5e5e9b.2a8cc18",
"group": "d9e6ccf5.f58ab",
"name": "Display Button",
"order": 0,
"width": 0,
"height": 0,
"format": "<!DOCTYPE html>\n<html>\n <head>\n <style>\n .button {\n background-color: #086A87;\n border: none;\n color: white;\n padding: 16px 32px;\n text-align: center;\n text-decoration: none;\n font-size: 16px;\n margin: 3px 1px;\n cursor: pointer;\n border-radius: 4px;\n }\n .button_over:hover {\n background-color: #187A97;\n color: white;\n }\n </style>\n </head>\n <body>\n \n <a href=\"http://127.0.0.1:1880/BARSU-SLD/\" class=\"button button_over\" target=\"_blank\" >SLD View</a> \n \n </body>\n </html>",
"storeOutMessages": false,
"fwdInMessages": true,
"templateScope": "local",
"x": 112,
"y": 195,
"wires": [
[
]
]
},
{
"id": "d9e6ccf5.f58ab",
"type": "ui_group",
"z": "",
"name": "Test",
"tab": "1474e3ec.fb238c",
"disp": true,
"width": "6"
},
{
"id": "1474e3ec.fb238c",
"type": "ui_tab",
"z": "",
"name": "Home",
"icon": "dashboard"
}
]
Any help is highly appreciable.
If you have httpStatic set to ~/.node-red/public, for example using the following in settings.js
httpStatic: path.join('', 'public'),
and if you have a file: ~/.node-red/public/images/myimage.png
Then your url should use the html
<img src="/images/myimage.png">
Note the initial / and the lack of any http://localhost:1880. You don't need to supply the http part since your browser will automatically match that up for you.
Just note also that if you have set httpRoot to something, you need to prefix your URL's with that as well.

Count Occurrences of Intrinsics Using Esprima

I am working on an application that allows user-submitted web-pages with embedded JavaScript code.
I would like to learn more about how my users are writing their JavaScript code, by building a map of common JavaScript intrinsics (built in objects) which shows the occurrence of each in user generated code.
Assume I have a JS file from a user's webpage:
Main.js
for (let i = 0; i < 10; i++) { myArrs.push(new Array()); }
let myObj = new Object();
I would like a script that can generate the following output:
Array: 10
Object: 1
I have attempted to do this using both regex and string traversal, but this does not account for the case where an item is used in an iteration. Simple string traversal would yield me with:
Array: 1
Object: 1
Which is not correct.
Esprima seems to provide a solution to this as it can perform syntactic analysis since it is a JS parser. I have attempted to use esprima.parseScript(input, config, delegate) to generate a tree and than traverse the tree but the output still does not take into account iterations.
Here is the output from my attempt at parsing this information using Esprima:
{
"type": "Program",
"body": [
{
"type": "ForStatement",
"init": {
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "i"
},
"init": {
"type": "Literal",
"value": 0,
"raw": "0"
}
}
],
"kind": "let"
},
"test": {
"type": "BinaryExpression",
"operator": "<",
"left": {
"type": "Identifier",
"name": "i"
},
"right": {
"type": "Literal",
"value": 10,
"raw": "10"
}
},
"update": {
"type": "UpdateExpression",
"operator": "++",
"argument": {
"type": "Identifier",
"name": "i"
},
"prefix": false
},
"body": {
"type": "BlockStatement",
"body": [
{
"type": "ExpressionStatement",
"expression": {
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"computed": false,
"object": {
"type": "Identifier",
"name": "myArrs"
},
"property": {
"type": "Identifier",
"name": "push"
}
},
"arguments": [
{
"type": "NewExpression",
"callee": {
"type": "Identifier",
"name": "Array"
},
"arguments": []
}
]
}
}
]
}
},
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "myObj"
},
"init": {
"type": "NewExpression",
"callee": {
"type": "Identifier",
"name": "Object"
},
"arguments": []
}
}
],
"kind": "let"
}
],
"sourceType": "script"
}
I was not able to find this answer on SO already - it seems like this is a useful problem to solve but requires a bit of knowledge in lexical analysis tools such as Esprima.

Categories