can't find regex for my usecase in nodeJS - node.js

I'm trying to register a property from a const in a .ts file. I stringified the file through readFileSync.
The const look like this :
environment = {
prop1: value,
prop2: env.prop,
propArray: ['','',''],
prop: host + 'somestring',
cancelLink: 'myvaluetocatch'
};
What regex would match with 'myvaluetocatch' associated with the cancelLink prop ?
If you have a way to parse a const from a .ts file without using import, could be great too :p
Thanks for your help.

You could use cancelLink: '(.*?)', but this is fragile and depends greatly on the style of the code you have written in your file and may produce false matches.
Live regex tester with your specific example here.

Related

populate object properties using lambda expression in typescript

Newbie Alert! I feel silly asking this question but I need someone to teach me the correct syntax.
I have code that looks like this:
let thing: INewThing;
thing.personId = another.personId;
thing.address = another.work.address;
thing.greades = another.subjectInfo.grades;
thing.isCurrent = another.student.isCurrent;
I know it can be written cleaner. I want to use a lamda expression, something like this:
let thing: INewThing => {
personId = another.personId,
address = another.work.address,
grades = another.subjectInfo.grades,
isCurrent = another.student.isCurrent
} as IThingUpdate;
I have looked and looked for an example. I have yet to find one that works for me. It's just syntax but no matter what I try it doesn't work.
You're just looking to create a new object, which is a pretty different thing from a "lambda" (function). Just declare the object. You don't need a function.
const thing = {
personId: another.personId,
address: another.work.address,
// use the correct spelling below - no 'greades'
grades: another.subjectInfo.grades,
isCurrent: another.student.isCurrent,
};
If the another is typed properly, that should be sufficient.
If the another object had more properties using the same path, another option would be to destructure those properties out, then declare the object with shorthand, eg:
const originalObj = { prop: 'val', nested: { foo: 'foo', bar: 'bar', unwanted: 'unwanted' } };
const { foo, bar } = originalObj.nested;
const thing = { foo, bar };
Destructuring like this, without putting the values into differently-named properties, helps reduce typos - if a property starts out, for example, as someLongPropertyName, putting it into a standalone identifier someLongPropertyName and then constructing an object with shorthand syntax ensures that the new object also has the exact property name someLongPropertyName (and not, for example, someLongPRopertyName - which isn't that uncommon of a mistake when using the more traditional object declaration format).
But since all the paths in your another object are different, this approach wouldn't work well in this particular situation.

Enum attribute in lit/lit-element

We are trying to build a component with a property variant that should only be set to "primary" or "secondary" (enum). Currently, we are just declaring the attribute as a String, but we were wondering if there is a better way for handling enums? For example, should we validate somehow that the current value is part of the enum? Should we throw an error if not?
I asked this question on Slack and the answers I got lean towards declaring the property as String and use hasChanged() to display a warning in the console if the property value is invalid.
Standard HTML elements accept any string as attribute values and don't throw exceptions, so web components should probably behave the same way.
This all sounds reasonable to me.
If you're using TypeScript I'd recommend just using strings. You can use export type MyEnum = 'primary' | 'secondary' to declare it and then use #property() fooBar: MyEnum to get build time checking. You can use #ts-check to do this in plain JS with #type MyEnum too.
This works well if the enums are for component options or that map to server-side enums that will get validated again.
However, if you want to validate user input into enums or loop through them a lot this is less good. As the JS runs it has no visibility of the type. You need an object dictionary, something like:
const MyEnum = Object.freeze({
primary: 'primary',
secondary: 'secondary'
});
// Enforce type in TS
const value: keyof MyEnum;
// Validate
const validated = MyEnum[input.toLower()];
// Loop
for(const enumVal of Object.keys(MyEnum)) ...
// Or Convert to a different value type
const MyEnum = Object.freeze({
primary: 1,
secondary: 2
});
These are somewhat idiosyncratic. Again, if you're using TypeScript it has an enum keyword that compiles to something like this and I'd use that rather than rolling your own. Strings are the better option unless you need to validate, loop or convert the values.

Is there a way to convert a graphql query string into a GraphQLResolveInfo object?

I have written a piece of software that parses and formats the fourth parameter of a graphql resolver function (the info object) to be used elsewhere. I would like to write unit tests for this software. Specifically, I do not want to build the GraphQLResolveInfo object myself, because doing that would be very cumbersome, error-prone and hard to maintain. Instead, I want to write human-readable query strings and convert them to GraphQLResolveInfo objects so I can pass those to my software.
After extensive googling and reading of the graphql-js source code, I have not found a simple way to do what they are doing internally. I'm really hoping that I am missing something.
What I am not trying to do is use the graphql-tag library, because that just generates an AST which has a very different format from the GraphQLResolveInfo type.
Has anyone done this before? Help would be much appreciated!
I will keep monitoring this question to see if a better answer comes along, but I've finally managed to solve my particular issue by creating as close an approximation of the GraphQLResolveInfo object as I need for my particular use case.
The GraphQLResolveInfo object is composed of several attributes, two of which are called fieldNodes and fragments. Both are in fact parts of the same AST that graphql-tag generates from a query string. These are the only parts of the GraphQLResolveInfo object that concern the software I wrote, the rest of it is ignored.
So here is what I did:
import gql from 'graphql-tag';
// The converter function
const convertQueryToResolveInfo = (query) => {
const operation = query.definitions
.find(({ kind }) => kind === 'OperationDefinition');
const fragments = query.definitions
.filter(({ kind }) => kind === 'FragmentDefinition')
.reduce((result, current) => ({
...result,
[current.name.value]: current,
}), {});
return {
fieldNodes: operation.selectionSet.selections,
fragments,
};
};
// An example call
const query = gql`
query {
foo {
bar
}
}
`;
const info = convertQueryToResolveInfo(query);
From the AST generated by graphql-tag, I extract and modify the operation and fragment definitions so that they look the way they do within the GraphQLResolveInfo object. This is by no means perfect and may be subject to change in the future depending on how my software evolves, but it is a relatively brief solution for my particular problem.

How to add multiline painless code in nodejs

So in my js-code I have this line:
var _script = {
_script: {
script: {
lang: 'painless',
source: `
"""
if(1>2){
params._source.id;
}
else{
params._source.id;
}
"""
`
},
type: 'string',
order: params._source.id
}
}
This will fail. I see in the log this error message:
,\"reason\":\"unexpected token ['\\\"\\\\n if(1>2){\\\\n params._source.id;\\\\n }\\\\n else{\\\\n params._source.id;\\\\n }\\\\n \\\"'] was expecting one of [{<EOF>, ';'}].\"}}}]},
I have tried first to have without tilde-character. And then it also fails.
I then tried to have tilde at the beginning, something like:
var _script = `{
Thing is that the final json that will be sent to elastic is not shown in the code above. So "_script" is only a little part of all the json.
I was wondering if I added the tilde at the very beginning and end of the whole json. Maybe it could work? I need to work it out where it is.
But just in theory: do you think the problem is there? Putting the tilde around all the json? Or is it something else?
The triple " is not valid JSON, it only works internally to the Elastic stack (i.e. from Kibana Dev Tools to ES).
The way I usually do it from Node.js is to add each line to an array and then I join that array, like this:
const code = [];
code.push("if(1>2){");
code.push("params._source.id;");
code.push("} else {");
code.push("params._source.id;");
code.push("}");
source = code.join(" ");
It's not super legible, I admit. Another way is to use stored scripts so you can simple reference your script by ID in Node.js.

Query value gets quoted automatically before sending it to MongoDB?

The following is confusing me a lot. I have been spending quite a bit of time trying to understand why collection.find() doesn't work with regex passed as an object. The regex match is coming over HTTP wrapped in the body of a POST request. Then I try to gather the query (in string format) and perform the query. The problem seems to be that unless the regex is written inside Node without quotes, it won't work. That is, it must be a literal without quotes.
For example, the following works fine:
var query1 = {
company: {
'$regex': /goog/
}
};
collection.find(query1, {}).toArray(function (err, docs) {
// Got results back. Awesome.
});
However, if the data comes wrapped in an object, it doesn't return anything. I suspect it's because the value gets quoted behind the scenes (i.e. "/goog/"):
// Assume
var query2 = {
company: {
'$regex': query.company
}
};
collection.find(query2, {}).toArray(function (err, docs) {
// Got nothing back.
});
I have tested it with the mongo shell and I can confirm the following:
// Returns 5 results
db.getCollection("contacts").find( { "company": /goog/ } )
// Doesn't match anything
db.getCollection("contacts").find( { "company": "/goog/" } )
Furthermore, I just discovered the following: if I write the value with quotes
// Works fine
var companyRegex = {'$regex': /goog/};
var query3 = {
company: companyRegex
};
So technically, a "literal" regex without quotes wrapped in an object works fine. But if it's a string, it won't work. Even after trying to replace the double-quotes and single-quotes with nothing (i.e. essentially removing them.)
Any idea how can I get the regex match be passed verbatim to find()? I've researched it, finding lots of potential solutions, alas it's not working for me.
Thanks in advance!
Let me focus on one line of your post. This is where the problem might be:
The regex match is coming over HTTP wrapped in the body of a POST request.
This seems problematic because:
The only structures that survive serialization between client/server are:
boolean
number
string
null *
objects and arrays containing these basic types
objects and arrays containing object and arrays [of more obj/array] of these basic types
Regexp, Date, Function, and a host of others require reconstruction, which means
passing a string or pair of strings for the match and option components of the Regexp and running Regexp() on the receiving end to reconstruct.
Regexp gets a bit messy because Regexp.toString() and Regexp() do not appear to be inverses of each others: /someMatch/.toString() is "/someMatch/" but RegExp("/someMatch/") is //someMatch// and what was needed instead to rebuild the regexp was just RegExp("someMatch"), which is /someMatch/. I hope this helps.
JSON.stringify(/someMatch/) is {} (at least on Chrome).
So instead of trying to build a general transport, I recommend re instantiating a particular field as a regexp.
* Irrelevant note: (null is fine but undefined is peculiar. JSON won't stringify undefineds in objects and turns undefined into null in Arrays. I recognize this isn't part of your problem, just trying to be complete in describing what can be serialized.)

Resources