20,173 Matching Annotations
  1. Nov 2021
    1. Honestly, I don't know. Strictly speaking it's different to a window being opened at a specific size (I can see the difference). I don't know whether that difference is material. Seeing as these are tests, I'd like to remove as many unknowns as possible. If someone can tell me that it makes no difference then I'd be happy.
    1. Info for maintainers Triage this issue by using labels. If information is missing, add a helpful comment and then I-issue-template label. If the issue is a question, add the I-question label. If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label. After troubleshooting the issue, please add the R-awaiting answer label. Thank you!
    1. But it is kind of verbose, and it’s also a lot slower, so I can understand why the model test might be preferred.
    2. If and when you need some kind of behaviour that waits for things, wait_until is a giant big sledgehammer. There are more fine grained, sophisticated tools built into Capybara, and I want you to learn about them, because those are some of the best features of the library. And when the built in tools aren’t enough, there are more sophisticated tools available than that clunky hammer. So hopefully the removal of wait_until encourages you to write better tests.
    3. I am firmly convinced that asserting on the state of the interface is in every way superior to asserting on the state of your model objects in a full-stack test.
    4. Even if #foo is originally on the page and then removed and replaced with a #foo which contains baz after a short wait, Capybara will still figure this out.
    5. The release of Capybara 2.0.0 removed the wait_until method from the API. This seems to have frustrated a few people,
    6. so let me explain why this decision was reached and what your options are for the future.
    7. wait_until was removed for several reasons:
    8. As long as you stick to the Capybara API, and have a basic grasp of how its waiting behaviour works, you should never have to use wait_until explicitly.
    9. Let’s make that really clear, Capybara is ridiculously good at waiting for content.
    10. apybara could have easily figured out how to wait for this content, without you muddying up your specs with tons of explicit calls to wait_until. Our developer could simply have done this: page.find("#foo").should have_content("login failed")
    11. Now after a long debugging session, our developer has found the timing issue. They now realize that there is a wait_until method in the API, and immediately think that, "hey, this sounds like what I need!"
    12. Its existence confuses people into thinking that it is necessary, when in fact it isn’t.
    1. I can't blame you. This problem seems anything but a newbie question! I was surprised when I noticed that this post (which was the only post I could find about trying to use chromedriver with flatpak chromium) in the linux4noobs forum. I've been using Linux as my primary desktop for ~15 years and this problem has stumped me too.
    2. Actually, I ended up uninstalling Chrome and installing a chromium deb. Since no chromium deb exists in Ubuntu or Pop OS repositories anymore, I followed the instructions from https://askubuntu.com/questions/1204571/how-to-install-chromium-without-snap to add the Debian stable repo and install Chromium from there instead.
    3. I'm having this problem too. Trying to use chromedriver with com.github.Eloston.UngoogledChromium (also tried org.chromium.Chromium) on Pop!_OS and selenium/webdriver (I'm using it with Ruby/capybara).This was the only post I could find (so far) about using chromedriver with a flatpak chrome/chromium... I wish someone would answer how or if this is possible.I created a chrome wrapper script that launches the flatpak, so that I could point to the script as my binary location. Did you do the same?It manages to open a window but the window is empty, and it just hangs for a hwile, and then eventually fails with:unknown error: DevToolsActivePort file doesn't exist (Selenium::WebDriver::Error::UnknownError) Any ideas how to get it working? I'd rather not install the "official" (proprietary software) Chrome binary on my system.Like you said, I never had any problems back in the good old days when we had deb packages for chromium. But now that we have to use a flatpak, I wonder if that's what the problem is — maybe chromedriver can't communicate directly with the chrome process because it is isolated/containerized??
    4. As soon as I installed a Chrome deb everything worked.sudo dpkg -i \~/Downloads/google-chrome-stable\_current\_amd64.deb It's unfortunate that that's the only way I could get it to work.
    5. Could someone guide me how to set up chromedriver with selenium using chromium flatpak properly? I can't seem to find any tutorial doing it like this... I never had issues with chromedriver using the "old" sudo apt way and I also got it working using snapd. But since I am using Pop!_OS I'd like to just use flatpaks if there is no sudo apt repo.
    1. apt-rdepends exists. This functionality should really reside in apt-cache itself.

      Update: Maybe it does already exist now. I was able to run this, for example without apt-rdepends being installed: apt-cache rdepends --installed libwebpmux3

    1. take advantage of LVM snapshots. Take snapshots before and after an upgrade. In case, if the system is in unrecoverable position, rollback to the last snapshot from a system rescue LiveCD. A useful program for this, as well as regular system backups is timeshift
    1. Although Flatpak is similar to Snap, I think it matches the freedom standards that many Linux users are usually looking for, much better than Snap.
    2. the snap-based chromium cannot access files on my separately-mounted /opt filesystem. The non-snap chromium has no such limitation. Until or unless the snap version ever is able to access all the filesystems on my device, I am willing to live with the risk of a PPA-based version.
    3. Perhaps not a good idea, in general, to use a random PPA for such sprawling software as a browser. Auditability near zero even if it is open source.
    4. I might just leave it installed, in case Canonical ends up replacing more important deb packages with snaps. (I might also drop Ubuntu if they do that.) As long as there isn't a snap directory cluttering my home dir, I can tolerate snapd lurking in the background for now.
    1. This is actively being worked on - for those interested you can follow the progress in https://github.com/snapcore/snapd/pull/10836
    2. Seeing how this has been treated for 4.5 years makes this seem like a pretty dysfunctional project. Please have mercy on your poor users and fix this.
    3. After 5 years there's still no fix. This is so annoying. I'm now getting rid of all snap packages and installing deb variants instead. Finally I'll purge snap and if these weird decisions keep on going I'll also move to another distro. Common Canonical. Seriously?
    1. In order to prevent this PR from becoming too large to review, I left the spread test, the part of this feature which makes it work with user daemons (left a TODO) and the addition of ~/Snap, for follow-up PRs.
    2. I find some of XDG's default dirs, especially ~/.local/share/whatever, to be very annoying. (Almost as annoying as having ~/snap polluting my home dir, but for a different reason.) I shouldn't have to type such long paths or navigate three folders deep in order to access my data files. I therefore make use of the XDG_DATA_HOME environment variable for XDG-style programs, so they will put my files somewhere convenient. However, I don't think Snap can honor that variable, because AppArmor rules require fixed paths. Given 1 & 2, I think ~/.snap/data is a sensible compromise, at least until the underlying components are flexible enough to let the user choose.
    3. Calling a software convention "pretty 90s" somewhat undermines your position. Quite a lot of well-designed software components are older than that. If something is problematic, it would be more useful to argue its faults. When someone cites age to justify change, I usually find that they're inexperienced and don't fully understand the issues or how their proposed change would impact other people.
    4. I hope you all will forgive my intrusion as a non-maintainer. Here's a perspective as a user:
    1. If you would like to use Google's cloud to store and sync your Chrome data but you don't want Google to access the data, you can encrypt your synced Chrome data with your own sync passphrase.
    1. he wanted a school board focused on the basics of education, not the abstract notions of social change some progressives say are at least as important as those basics
    2. On two highly divisive cultural issues — public safety and public education — even voters in this exceedingly progressive city have bluntly told their elected leaders that high-minded rhetoric is not enough.
    1. I'll use any of them, so long as it's not somebody's proprietary BS.But even if Canonical gave up on keeping all of Snap distribution private in-house, it would still be my last choice because of all the issues Snaps have (and other options don't).
    2. They wanna be to Linux what the Play Store is to Android, what the App Store is to iOS.But we don't do that around here. We use Flatpak round 'ere.

      annotation meta: may need new tag: company [aspiring] to be bigger / take over the world

    3. Pop!_OS has remained Snap-free so far. Ubuntu 21.10 will switch to the Snap version of Firefox. Firefox is the default browser of Pop!_OS. By 22.04 System76 will probably have to maintain the Firefox deb themselves.As Canonical switches more and more debs to Snaps, System76 will have to maintain more packages on their own and the Ubuntu base becomes more and more useless to them.So ultimately, System76 will either have to go full Snap with Pop!_OS (which will cause many, including myself, to abandon it) or abandon the Ubuntu base.
    4. Because flatpaks are distro agnostic, while you may prefer to have the distro's native package format you have to understand maintaining a a deb, rpm, etc simultaneously can be a real pain in the ass that you either deal with or you simply choose not to support certain formats and thus certain distros. With Flatpak is one package for all distros, or at least that's the idea.
    5. The reason is that all mainstream OS makers are moving towards a radical new paradigm for OSes called 'immutable' systems (apple recently completed this transition, ms failed twice and pins its hopes on win11, linux distros are held back by a requirement for lightweight container formats to gain a foothold first before decreasing mutability then switching to read-only system partitions).Immutability trended first for servers, where canonical gained some success early before pushing for snaps for desktop. Its a way to guarantee a system does not deviate from a 'know good' state and neither its reliability or hardware compatibility/certifications change across updates.
    6. For example, if your machine has a lot of RAM doesn't mean all apps should then use as much of it as possible.
    7. I am concerned with duplicated dependencies though, that's my primary aversion to flatpak/snap/AppImage/etc.
    8. This doesn't solve the problem of supporting where the users are; not everyone wants to use a rolling release, not everyone has the same kernel version, and so on. Not all distros support deb packages.If everyone was on Arch, then AUR would solve everyone's problem. If everyone was on Fedora, then RPM would solve everyone's problem but we don't have that universal packaging system.Freedom to pick and choose what you want to use on Linux is what makes it fun but for people that are trying to develop software and share it with their customers on linux, it's super complicated; they don't have a way to ship software to everyone in one simple package.Software devs can't just ship a deb package. That eliminates the large number of RPM based users such as Fedora, RedHat Fedora Enterprise, CentOS Stream or other distros. Then you have the Arch users, etc.That's what Flatpack/snap/appimage can help with.
    9. packaging is difficult to maintain on linux with so many different distros that software companies to support.Flatpak, snap, and appimage makes it easier to ship once for a lot of distros that support them.
    10. Flatpack is just a slightly less crappy snap.
    11. And this is why I left Ubuntu. If I want a SNAP I will install a SNAP. Otherwise stay out of my crap.
    1. The answer is No. You have to have the chrome application inside your computer. However, you do not need t install it. It will work with any portable Chrome versions as well. You simply have to point to the chrome executable location during tests.
    1. Zen Magnets founder Shihan Qu prepares high-powered magnet balls for destruction at the Metal Treating & Research Co. in Denver on April 26. A federal judge ordered Qu to eliminate the magnets as part of a long-running battle over the magnets' safety.
    1. What’s your least favorite thing to do, and how do you deal with it?Probably tradeshows or being on Fox and Friends talking about government regulation. I’m more of a behind-the-scenes brand and design guy so any forced sales-y activity puts me a little out of my comfort zone. I love the design process, but talking with Steve Doocey, managing 100 sales reps and 3,000 retail accounts is still something we’re looking for help on.
    2. Anything by Chuck Klosterman.
    3. I also got into Ayn Rand and George Orwell during the Buckyballs v. The Man days.
    1. 1) Order the one for your particular vehicle if you can otherwise the curvature of the side rails may not be correct which will dent the metal once secured.2) Look/feel under the headliner if you can prior to drilling into the roof, you may hit a beam which will be troublesome running a screw through multiple pieces of metal. You can also cut the side rails if necessary.3) Use non-corrosive silicone (does not smell like vinegar which will eventually eat away at the paint and rust) to seal up the holes that you drill into the roof. End caps doesn't appear to make a tight seal.4) Screws are stainless which are typically soft. Be careful not to overnighten! I actually used a rivnut/blind nut tool instead of just screws (About 25 bucks here on Amazon).
    1. /!\ If you see "Complete the captcha then press enter", switch to the Chromium window and do the captcha. ¨¨ Press Enter when you're done, the page will reload and you should see the source code of the URL you request
    2. This code permit a manual bypass of the CloudFare captcha for FanFiction.net
    1. Alternatively, you could create a weak relationship: interface WeakHashmap<V> { [key: string]: V[keyof V]; }
    2. type Hashmap<K, V> = { [k in K]: V; }
    3. const palette: { [key: string]: string } = {...
    4. However, unless my feeble brain is feeble, this looks like a valid use case and I might not be alone.
    5. Of course, we can always add more special cases to the type system to detect the specific case of iterating over a known-bounded object literal, but this just leads to the "Why does this code not behave like this other nearly-identical code?" problem when we fail to properly exhaust all the special cases.
    6. Regarding the first example, we have to put aside the fact that we (from inspection) can see the runtime behavior of this code by executing it in our heads.
    7. Regarding mapped types, remember that { [K in T]: U } is a special form - it can't be combined with other properties within the { }. So there's not really a name for the [K in T: U] part because it's just part of the overall "mapped type" syntax { [K in T]: U }
    8. what is the TypeScript Way™ of handling the implicit any that appears due to object literals not having a standard index signature?
    9. Even if it's const, an object can still have properties added later returning any arbitrary type. Indexing into the object would then have to return any - and that's an implicit any.
    10. fresh (i.e. provably do not have properties we don't know about)
    11. Object literals don't have index signatures. They are assignable to types with index signatures if they have compatible properties and are fresh (i.e. provably do not have properties we don't know about) but never have index signatures implicitly or explicitly.
    12. Which... is confusing because Palette technically does have an index signature Palette is a mapped type, and mapped types don't have index signatures. The fact that both use [ ] is a syntactic coincidence.
    13. I thought I knew how they worked, but it looks I was wrong and made two false assumptions: Thought that typeof of object literals are inferred to have (string | number) index signature Thought that mapped types over union of string literals is a way to declare a limited set of string index signatures That's how it looked to me from the example in Typescript Deep Dive
    14. type PaletteColors = keyof typeof palette type Palette = { [Color in PaletteColors]: string }
    15. What you wrote is called a Mapped Type (horrible name for trying to google it).
    16. Generate type with the index signature: interface RandomMappingWithIndexSignature { stringProp: string; numberProp: number; [propName: string]: string | number | undefined; }
    17. we have no way to know that the line nameMap[3] = "bob"; isn't somewhere in your program
    1. I suggest renaming this to something like SomeInterfaceAsTypeWrittenByHand. Because one of the reasons for Simplify is so you don't have to write SomeType by hand. Then add the following to show that Simplify<SomeInterface> is the same as SomeInterfaceAsTypeWrittenByHand. declare const a: Simplify<SomeInterface>; expectType<SomeInterfaceAsTypeWrittenByHand>(a); // Interface is assignable to its Simplified type (created with Simplify, and by hand) expectType<Simplify<SomeInterface>>(someInterface); expectType<SomeInterfaceAsTypeWrittenByHand>(someInterface);
    1. considering people rarely make meta posts about how great their question was received, it's pretty expected that it'd be net negative.
    2. The meta effect refers to the community reaction to certain posts here on Meta, in particular posts that point to another post on Stack Overflow. This tends to be a negative effect - people who come to complain/ask about posts on Stack Overflow on Meta are essentially inviting scrutiny and review of these posts. More often than not, it means a flurry of downvotes, close votes and delete votes on a post.
    3. The term describes this effect - that's its purpose.
    1. I posted a question about MD5 hash collision back in 2014. As far as I know questions about algorithms are on-topic on Stack Overflow, and the cryptography tag did not have the warning "CRYPTOGRAPHY MUST BE PROGRAMMING RELATED" back then.
    2. Stack Overflow is full of old "not directly programming related" cryptography questions, that are highly upvoted. Those have to be closed/locked as well?
    3. The rule applies in all cases. It is impossible to migrate questions that are more than 60 days old, even for moderators.
    4. in my opinion it could have been more constructive to move this question to cryptography stack exchange, instead of downvoting and closing it.
    5. They opened a question here on meta, and suddenly my question got 25 downvotes, and eventually got closed for being off-topic.
    6. Someone reported it for being off-topic, but a mod declined it with a comment "I see no reason why this is off-topic. Not a programming question? You must surely be joking!", so it seems that this is controversial for the mods as well.
    1. Determine if the string's length is greater than num. Return the string truncated to the desired length, with '...' appended to the end of the original string. Copyconst ellipsis = (str: string, num: number = str.length, ellipsisStr = "...") => str.length >= num ? str.slice(0, num >= ellipsisStr.length ? num - ellipsisStr.length : num) + ellipsisStr : str;
    1. The other commenters are right about the potential solutions. However, it is actually considered a best practice to move the object with the index signature to a nested property.Said differently: No property in the object with the index signature should depart from how the index signature is typed.
    2. Like others have noted, your function does not conform to index signature. [key: string]: string means "all fields are strings" and on the next line you declare a field with function in it.This can be solved by using union types:type IFoo = { [foo: string]: string } & { fooMethod(fooParam: string): void }
    1. you can define locally parse and it should take precedence over the one in the library: interface JSON { parse(text: string, reviver?: (key: any, value: any) => any): unknown; }
    2. This PR adds a new top type unknown which is the type-safe counterpart of any. Anything is assignable to unknown, but unknown isn't assignable to anything but itself and any without a type assertion or a control flow based narrowing. Likewise, no operations are permitted on an unknown without first asserting or narrowing to a more specific type.
    1. // Second case (unexpected) interface C { [x:string]: number } interface D { x: number } const d: D = { x: 1 }; const c: C = d; // error // Type 'D' is not assignable to type 'C'. // Index signature is missing in type 'D'.
    2. Seems related, currently there's no way to enforce that object should have attribute values of specific type only. Example: I want to define an abstract Table Row, basically any object limited to attribute values as primitive types. But it doesn't work // Table row export type Row = Record<string, string | number | undefined> // User interface User { name: string } const jim: User = { name: 'Jim' } const row: Row = jim // <== Error
    1. So now the question is, why does Session, an interface, not get implicit index signatures while SessionType, an identically-structured typealias, *does*? Surely, you might again think, the compiler does not simply deny implicit index signatures tointerface` types? Surprisingly enough, this is exactly what happens. See microsoft/TypeScript#15300, specifically this comment: Just to fill people in, this behavior is currently by design. Because interfaces can be augmented by additional declarations but type aliases can't, it's "safer" (heavy quotes on that one) to infer an implicit index signature for type aliases than for interfaces. But we'll consider doing it for interfaces as well if that seems to make sense And there you go. You cannot use a Session in place of a WithAdditionalParams<Session> because it's possible that someone might merge properties that conflict with the index signature at some later date. Whether or not that is a compelling reason is up for rather vigorous debate, as you can see if you read through microsoft/TypeScript#15300.
    2. why is Session not assignable to WithAdditionalParams<Session>? Well, the type WithAdditionalParams<Session> is a subtype of Session with includes a string index signature whose properties are of type unknown. (This is what Record<string, unknown> means.) Since Session does not have an index signature, the compiler does not consider WithAdditionalParams<Session> assignable to Session.
    1. import {isDefined} from 'ts-extras'; [1, null, 2, undefined].filter(isDefined); //=> [1, 2]
    2. The type-fest package contains only types, meaning they are only used at compile-time and nothing is ever compiled into actual JavaScript code. This package contains functions that are compiled into JavaScript code and used at runtime.
    1. Having actual functions here is a non-goal. This package is for types only, meaning nothing ends up compiled into actual JS code.
    2. I am not sure about aliases though... The number of aliases for various type definitions could grow without bounds. Unless it is a very common usage Indexify, my 2 cents would be not to create an alias. But I don't make the call on this.
    3. An interface can be re-opened. Whereas a type is sealed. So a solution for microsoft/TypeScript#15300 is to map the interface (which can be defined in many places) to a type.
  2. Oct 2021
    1. Object.hasOwn() is recommended over hasOwnProperty(), in browsers where it is supported.
    2. The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
    1. const str = 'mañana mañana' const strReverse = str.split('').reverse().join('') // => "anãnam anañam" // notice how the first word has an ã rather ñ
    1. However, this way of thinking about the built-in sameness operators is not a model that can be stretched to allow a place for ES2015's Object.is on this "spectrum". Object.is isn't "looser" than double equals or "stricter" than triple equals, nor does it fit somewhere in between (i.e., being both stricter than double equals, but looser than triple equals). We can see from the sameness comparisons table below that this is due to the way that Object.is handles NaN. Notice that if Object.is(NaN, NaN) evaluated to false, we could say that it fits on the loose/strict spectrum as an even stricter form of triple equals, one that distinguishes between -0 and +0. The NaN handling means this is untrue, however. Unfortunately, Object.is has to be thought of in terms of its specific characteristics, rather than its looseness or strictness with regard to the equality operators.
    2. A model for understanding equality comparisons
    1. For those coming from Ruby, Javascript has no builtin method like Ruby’s Array#compact.
    2. Another option is the use the functional library Ramda, while the syntax may be a bit different from the Ruby and Pure JS version, I find it to be more declarive: list = [null, "say", "kenglish", "co", null] R.reject(R.isNil, list) // return new array [ 'say', 'kenglish', 'co' ]
    1. The issue seems to be that when there are multiple layouts configured, VS Code sets as key layout the first value for layout form setxkbmap -query, ignoring the current layout. If I switch to be en,de then VS Code uses the EN layout, as it is the first in the list. It would be handy if VS Code could use the current layout instead of the first from the list.
    1. xdotool key ctrl+R;
    2. jq '.profile.exit_type= "Normal" | .profile.exited_cleanly = true' ~pi/.config/chromium/Default/Preferences
    3. sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/Default/Preferences sed -i 's/"exit_type": "Crashed"/"exit_type": "Normal"/' ~/.config/chromium/Default/Preferences
    4. The best way to now perform this task, without having to use incognito, is to adjust two settings in the Chromium preferences. They are: exited_cleanly exit_type
    1. Disable features that inhibit control and transparency, and add or modify features that promote them (these changes will almost always require manual activation or enabling).
    2. In addition, Google designed Chromium to be easy and intuitive for users, which means they compromise on transparency and control of internal operations.
    1. We will also show you how to de-link your Chrome profile from your Google account(s) by stopping Chrome from syncing with Google in the first place. This will help keep your Chrome profile separate from your Google account and enhance your online privacy.
    2. To do that, Chrome automatically links your Chrome profile to a Google account when you sign in to any Google service on the web. That helps Google deliver a ‘seamless experience’ across all devices by letting you sync your history, bookmarks, passwords, etc., across multiple devices. Meanwhile, privacy-conscious users see this as a major threat to their online privacy and advise users to remove their Google account from Chrome.
    3. As mentioned already, Chrome automatically signs you in to your Google account every time you sign into a Google service, like Gmail, YouTube, Google Photos, etc. It also links your current Chrome profile to that account. While Google says that it does so to offer a ‘seamless experience’, it is a privacy nightmare for many users.
    1. Some Chrome users may like the new functionality as it makes it easier for them to sign in or out of Chrome and Google on the Web. Others may dislike it for privacy and user-choice reasons. Think about it, if you sign in to Chrome you are automatically recognized by any Google property on the web as that Google user.
    1. I have all my bookmarks and settings attached to an account which is part of a Gsuite i'm not part of anymore, so i want to resync my chrome with my personal account, but I don't know how to import all the bookmarks and settings from the old Gsuite account to my personal one

      I can relate...

    1. let bookmarkList = Array.from(document.querySelectorAll('.widget>.vbox')) .map(e => e.shadowRoot) .map(e => e && e.querySelector('.device-page-list')) .find(e => e); let bookmarks = Array.from(bookmarkList.querySelectorAll('.vbox')) .map(e => `[${e.querySelector('.device-page-title').innerHTML}](${e.querySelector('x-link').innerHTML})`); copy(bookmarks.join('\n'));
    1. Having a large extension ecosystem is something that can help deal with the lack of certain capabilities, as third-party developers can create their own add-ons that others might find useful as well.

      can create your own

    2. Exporting your active tabs to a TXT or HTML file is something that many people want to do, but which is impossible right now in Google Chrome without turning to an extension.
    1. Desktop files are NOT executed. The line inside them that has an executable command line is the one that gets executed. The rest of the file is parsed by the Desktop Environment.
    2. Upvoted on techical merit; but the correct answer which should be accepted is
    3. Please note that gtk-launch requires the .desktop file to be installed (i.e. located in /usr/share/applications or $HOME/.local/share/applications). So to get around this, we can use a hackish little bash function that temporarily installs the desired .desktop file before launching it. The "correct" way to install a .desktop file is via desktop-file-install but I'm going to ignore that.
    1. Analytics is the key to understanding your app's users: Where are they spending the most time in your app? When do they churn? What actions are they taking?
    1. Users are only counted in the steps they complete in the specified sequence. If the user misses a step, they fall out of the funnel and aren't counted in any subsequent steps.
    1. const fetchWithJSONHeaders = applyDefaults(fetch, { headers: { "Content-Type": "application/json" } }); const fetchWithTextHeaders = applyDefaults(fetch, { headers: { "Content-Type": "application/text" } }); // Fetch JSON content const response = await fetchWithJSONHeaders("/users", { method: "GET" });
    2. function applyDefaults(fetchFn: typeof fetch, defaults: Required<Parameters<typeof fetch>[1]>)
    3. In rare cases, the underlying types aren't exposed from the library. What shall we do then? Maybe we could also use the typeof operator here too and combine it with a TypeScript's built-in type Parameters. Parameters becomes useful whenever you want to extract the type of parameters from a function type:
    1. But there is a lot of things we didn’t handle: How do we pass function arguments through? How do we maintain scope (the value of this)? How do we get the return value? What if an error happens?
    1. A wrapper function is a design concept where a very minimal function is using another function to do it's "work" for it, sometimes using a slightly different set of arguments.
    1. From a client side/application (as a whole) standpoint this is an internal endpoint, for the router of SvelteKit this would be an external resource.
    2. I interpreted it more like "you can (for example) use serverFetch for external resources", rather than "serverFetch is exclusively for fetching external resources"
    3. So if I just forward the cookie header (which contains the access-token), wouldn't that be just what I am not supposed to do. I mean what's the point of using 'HttpOnly' flag if I return the token to the client-side js on every request.
    4. while with server/externalFetch there is no direct way to pass cookie headers from the original request to the external one
    5. You're right, this discussion is starting to go off on a tangent.
    6. Honestly, I think the current discussion has nothing to do with my original issue anymore.
    7. With httponly you only prevent to read the cookie with js, but its still possible to make requests in the name of the user.
    8. They are on client-side, but (usually) they are HTTPOnly. Now if they are part of session, any client-side script is able to access them, and I just don't like introducing vulnerabilities knowingly. As I said above, I found a workaround that works for me and you may have different opinion from me on how much this is a risk.
    9. Right now I am working around this issue by having an internal [...api].js, then call fetch for that endpoint (which automatically passes on cookies) and from there hit the actual external endpoint. It works, there is no risk of leaking anything, but imo shouldn't be necessary.
    10. Sure you can abuse session but I don't like that since there is the risk of exposing credentials to client side code.
    11. Also the problem becomes even worse if you multiple api/resource servers and have to decide in each load function which credentials should be exposed to which server.
    12. I am currently circumventing this issue by using getSession to have access to the cookies/headers in the load method

      We did something similar for a while...

    13. that is not ideal, since for example 'Cookie' is a forbidden header name, so I have to start worrying about env in load, which is kind of contra to its design.
    1. serverFetch name is unclear. That the docs need to say in bold that it's external is a bit of a code smell.
    2. Rename to externalFetch. That it runs on the server is already implied by it being located in hooks
    1. This function allows you to modify (or replace) a fetch request for an external resource that happens inside a load function that runs on the server (or during pre-rendering). For example, your load function might make a request to a public URL like https://api.yourapp.com when the user performs a client-side navigation to the respective page, but during SSR it might make sense to hit the API directly (bypassing whatever proxies and load balancers sit between it and the public internet).
    1. You do not configure Zeitwerk manually in a Rails application. Rather, you configure the application using the portable configuration points explained in this guide, and Rails translates that to Zeitwerk on your behalf.
    2. Inflections go the other way around.In classic mode, given a missing constant Rails underscores its name and performs a file lookup. On the other hand, zeitwerk mode checks first the file system, and camelizes file names to know the constant those files are expected to define.While in common names these operations match, if acronyms or custom inflection rules are configured, they may not. For example, by default "HTMLParser".underscore is "html_parser", and "html_parser".camelize is "HtmlParser".
    3. All these problems are solved in zeitwerk mode, it just works as expected, and require_dependency should not be used anymore, it is no longer needed.
    4. For example, there is no point in defining reloadable Rack middleware, because changes would not be reflected in the instance stored in the middleware stack anyway