-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get getQueryString to expect relative URLs too #50
Conversation
@gelbal @pranasziaukas I added the logic to handle both relative and absolute Urls and corresponding tests that seem to be working. But as always, please give it a look since you might come up with a better way to handle this or notice something I missed. Thanks! |
@laziob I see balenaCI returns failed because of not-prettified code. Can you please run
I wonder if it makes sense to include |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff pushing this forward Ezequiel. I typed couple of suggestions and discussion points.
} | ||
|
||
// If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. | ||
if (typeof destinationUrl === 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can combine this if
statement with the one above to eliminate the double check for string
. The code and comments will also read better.
if (typeof destinationUrl === 'string') {
if (destinationUrl.match(relativeRegex)) {
return '';
} else {
....
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gelbal Lol I was going to do it that way first, but for some reason I remembered that once I saw the if statements one below the other and that that was the usual practice or something like that and went the other way. Sure I'll change that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@laziob oh I see you made a major rework. Actually I liked your previous implementation as it was cleaner (once you combine the new if
statements). So the code handles the string
scenario first and the proceeds to handling the URL
scenario. Can you please bring it back? : )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Petros (ex-CTO) made a pretty good presentation about such design principle actually (he calls it normalizing if
). I highly recommend listening to it:
https://docs.google.com/presentation/d/1hFV5YBL4FflfN7OIJr6eZrUV4Pk158wOXWzea1ANTnM/edit#slide=id.p
https://drive.google.com/file/d/1xtHev7HUwbASdasf8cWfG9O2oHdlXX43/view
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gelbal It still handles the string scenario first. The code above is for the other parameter that stays that way regardless of the destinationUrl
. The reason I changed it was because with the previous design, I had to repeat much more code, once for each if and even then couldnt make it work properly. In fact I dont even like this design, since it still repeats code. But it repeated less than the previous one. I still also dont believe we should be handling relative URLs through this method. It kind of undermines the use of TypeScript and gives place to the bad use of the method in resin-site
, since I still think they shoudnt be forcing this method in every link "just in case". Performance wise it doesnt make sense to me. resin-site
should have a better way to identify outbound links from inbound links, and call this method only on outbound links.
Having said that, I could try go back to the previous design, but I could make it work with the previous design. This was so far the only way I achieved what I wanted lol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To put an example, Hub
handles it like this:
deployUrl = getExternalLinkWithTracking( 'https://dashboard.balena-cloud.com/deploy?repoUrl=${repoUrl}')
So it explicitly uses the method on the only domain where its needed. For example marketing site only needs to use it on the Login and Signup buttons, which exist only in 2 places, the header (for most of the resin-site pages) , like here and the box for on the landing page.
So its not that they need to detect relative urls in a simple way. Its that they have to detect URLs to another balena domain, not even including subdomains.
If using a list is the best way to do it I dont really know, but if its needed to be raised for further discussion Im up for that. Whats the proper way and place to raise it? ALthough It just seems too much for the task at hand tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gelbal we need to work on this soon since its the only thing preventing marketing sites to update to the last analytics client. Its still using 0.12 so its not stiching sessions nor using the last referrer updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iamsolankiamit @thgreasi @JSReds if you could take a look into the discussion too so we can decide on how we advance it would be really helpful and appreciated! thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @laziob cc @thgreasi @JSReds @iamsolankiamit, how about introducing an optional parameter (in the analytics-client
constructor) for a list of domains to track?
We could retrieve this list either directly from the client that calls analytics-client
or indirectly from the projectName
configuration stored in the analytics-backend
. At first it'll have the following content:
*.balena.io
*.balena-cloud.com
We will probably end up updating this list seldom so it's not a big maintenance issue to store it on the analytics-backend
side.
Edit: Thinking it further, part of my suggestion actually means that analytics-client
needs to retrieve such stateful information from the analytics-backend
at each initialization. So maybe that's a no-go. It's cleaner for the component to configure analytics-client
directly (without dependency on the backend).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having said these, let's still go ahead with working on this PR to add support for relative URL detection.
src/url-params.ts
Outdated
|
||
// If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. | ||
if (typeof destinationUrl === 'string') { | ||
destinationUrl = new URL(destinationUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to handle the errors here when the incoming string cannot be translated to a URL. I'm not sure if relativeRegex
ensures that the string with no match is actually a URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gelbal Ohh yeap you are right. let me look into this.
src/url-params.ts
Outdated
? destinationDomainMatch.toString() | ||
: null; | ||
} catch (err) { | ||
return ''; //I dont know what we should do when an error like this happens. Any ideas?? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. We could do console.log(err)
but I don't know how much that'd help. I think it's fine to at least catch it as you do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thgreasi @iamsolankiamit any suggestions on handling such caught errors in modules?
It's OK to silently fail here but I wonder what's the best practice.
// this regex is based on the assumption that we wont be using TLDs longer than 3 characters. If we do, it will break | ||
// the logic and take that longer TLD as the main domain, for example hub.balena.edge.io -> edge.io | ||
const regex = /([a-zA-Z0-9-]+)(\.[a-zA-Z]{2,3})?(\.[a-zA-Z]+$)/g; | ||
|
||
let actualDomainMatch; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually prefer it here, next to where it's first assigned, so that's easier to follow.
Also type it as:
let actualDomainMatch: RegExpMatchArray | null;
src/url-params.ts
Outdated
let destinationDomainMatch; | ||
let destinationDomain; | ||
let actualDomainMatch; | ||
let actualDomain; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these are typed as any
, which isn't good...
After the changes suggested bellow this will be:
let destinationDomainMatch; | |
let destinationDomain; | |
let actualDomainMatch; | |
let actualDomain; | |
let destinationDomain: string | undefined; |
but I would suggest to push it lower, near the place it's first assinged.
src/url-params.ts
Outdated
const destinationDomainMatch = destinationUrl | ||
? destinationUrl.hostname.match(regex) | ||
: null; | ||
actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; | |
const actualDomain = actualDomainMatch ? actualDomainMatch.toString() : null; |
and if you have recent enough TS in this project, then you can do:
const actualDomain = actualDomainMatch?.[0]; // this is inferred as `string | null` automatically
prefer explicitly reading the first match, that relying on toString()
.
src/url-params.ts
Outdated
if (typeof destinationUrl === 'string') { | ||
try { | ||
destinationUrl = new URL(destinationUrl); | ||
destinationDomainMatch = destinationUrl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destinationDomainMatch = destinationUrl | |
const destinationDomainMatch = destinationUrl |
Just declare it in this scope, since this is only used in this limited scope as a temp variable and its value isn't useful outside this context.
src/url-params.ts
Outdated
return ''; //I dont know what we should do when an error like this happens. Any ideas?? | ||
} | ||
} else { | ||
destinationDomainMatch = destinationUrl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destinationDomainMatch = destinationUrl | |
const destinationDomainMatch = destinationUrl |
Just declare it in this scope, since this is only used in this limited scope as a temp variable and its value isn't useful outside this context.
src/url-params.ts
Outdated
destinationDomain = destinationDomainMatch | ||
? destinationDomainMatch.toString() | ||
: null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destinationDomain = destinationDomainMatch | |
? destinationDomainMatch.toString() | |
: null; | |
destinationDomain = destinationDomainMatch?.[0]; |
src/url-params.ts
Outdated
destinationDomain = destinationDomainMatch | ||
? destinationDomainMatch.toString() | ||
: null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destinationDomain = destinationDomainMatch | |
? destinationDomainMatch.toString() | |
: null; | |
destinationDomain = destinationDomainMatch?.[0]; |
dd34960
to
c6811c1
Compare
@gelbal I think I properly reverted to the previous way we handled the relative URLs, hadnling string first and so but keeping some error handling. The unit tests are still working properly too. So please take a look when possible. On the other hand, I still dont know whats the best way to pass href and window.location.hostname as arguments to getQueryString() on the resin-site side here which is adressed on the PR though but with no solution yet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff @laziob. I like this version the best.
The error you get is:
Error: File src/url-params.ts hasn't been formatted with prettier
Can you please call npm run prettify
and squash all your commits before pushing once more?
src/url-params.ts
Outdated
return ''; | ||
} | ||
|
||
// If its not a relative URL string, we make sure if its a string or an URL. It its a string, we convert it to an URL object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a comment here as the code is self explanatory.
src/url-params.ts
Outdated
? destinationDomainMatch.toString() | ||
: null; | ||
} catch (err) { | ||
return ''; //I dont know what we should do when an error like this happens. Any ideas?? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thgreasi @iamsolankiamit any suggestions on handling such caught errors in modules?
It's OK to silently fail here but I wonder what's the best practice.
Change-type: Minor Signed-off-by: Ezequiel Boehler [email protected]
c6811c1
to
43e9be3
Compare
Hey @laziob, clicking on the
It's best to get rid of that comment anyhow. Can you please add Exposing the error seems more useful than harmful. On other news, is this PR waiting for some other changes? |
…a-io-modules/analytics-client into getQueryString_expect_relative_url
@balena-ci I self certify! |
Change-type: Minor
Signed-off-by: Ezequiel Boehler [email protected]