fix(types): Add type safety to browser.runtime.executeScript files option#2142
Conversation
✅ Deploy Preview for creative-fairy-df92c4 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| WxtBrowser["scripting"]["executeScript"] | ||
| >[0] & { files: Array<${paths.join(' | ')}>; func?: never | undefined }; | ||
|
|
||
| type ReplaceFirstArg<Fnc, Arg> = Fnc extends { |
There was a problem hiding this comment.
tbh: Not a big fan of this typescript magic, so open to other suggestions
There was a problem hiding this comment.
Alternatively, @aklinker1 curious if it's an option to update the backing @wxt-dev/browser package to have a generic T for file paths, which we can dynamically declare when generating the declaration file based on the filenames
There was a problem hiding this comment.
@nickbar01234 Did you try how we do it here?
wxt/packages/wxt/src/core/generate-wxt-dir.ts
Lines 89 to 108 in 430a3ac
wxt/packages/wxt/src/browser.ts
Lines 14 to 31 in 430a3ac
We should be able to simplify this quite a bit. Unless there's something different about what you're doing here.
There was a problem hiding this comment.
if it's an option to update the backing @wxt-dev/browser package to have a generic T for file paths, which we can dynamically declare when generating the declaration file based on the filenames
I'm hesitant to make excessive changes to that package since it's generated based on @types/chrome. It may be possible to automate, but it would become more fragile. I'd prefer we use the existing patterns for augmenting the browser types
There was a problem hiding this comment.
Gotcha, I think I see what wxt/packages/wxt/src/browser.ts is doing. Let me try refactoring this code to match the pattern
| type ScriptInjection<Args extends any[], Result> = | ||
| Browser.scripting.ScriptInjection<Args, Result> extends infer T | ||
| ? T extends { files: string[] } | ||
| ? Omit<T, 'files'> & { files: ScriptPublicPath[] } |
There was a problem hiding this comment.
API docs say that file injections can be either CSS or JS, which does not align with my understanding of executeScript API.
The path of the JS or CSS files to inject, relative to the extension's root directory. Exactly one of the files or func must be specified.
If this is the case, we'd need to add more union to ScriptPublicPath. The other concern is downstream consumers with wrong file name will break when they pick up this version. My thought is that it's ok for better type safety
There was a problem hiding this comment.
I agree, it should be fine for now.
MDN doesn't include CSS files in their docs: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript
I'd say it's fine for now, if someone opens an issue we'll know what needs added.
|
@aklinker1 just updated the implementation whenever you have some downtime to review! |
browser.runtime.executeScript files option.
aklinker1
left a comment
There was a problem hiding this comment.
Perfect, thanks. Much simpler!
packages/wxt/src/browser.ts
Outdated
| interface WxtScripting { | ||
| executeScript: { | ||
| <Args extends any[], Result>( | ||
| injection: ScriptInjection<Args, Result>, | ||
| ): Promise<InjectionResult<Result>>; | ||
|
|
||
| <Args extends any[], Result>( | ||
| injection: ScriptInjection<Args, Result>, | ||
| callback: (results: InjectionResult<Result>) => void, | ||
| ): void; | ||
| }; | ||
| } |
There was a problem hiding this comment.
Huh, I guess we don't need to generate some of the overrides per-project, like the runtime overrides... I could just import the PublicPath type like you did here...
There was a problem hiding this comment.
not too familiar with the typescript build process itself, so I was mostly referencing https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/utils/inject-script.ts#L4-L8 that also uses the public type before they existed
There was a problem hiding this comment.
Yeah, I think I'll move to this when possible. Modules like i18n will still need to generate it's own module augmentations, but the static stuff can be put here.
browser.runtime.executeScript files option.browser.runtime.executeScript files option
@wxt-dev/analytics
@wxt-dev/auto-icons
@wxt-dev/browser
@wxt-dev/i18n
@wxt-dev/module-react
@wxt-dev/module-solid
@wxt-dev/module-svelte
@wxt-dev/module-vue
@wxt-dev/runner
@wxt-dev/storage
@wxt-dev/unocss
@wxt-dev/webextension-polyfill
wxt
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2142 +/- ##
==========================================
+ Coverage 75.94% 76.14% +0.19%
==========================================
Files 113 113
Lines 3043 3043
Branches 680 680
==========================================
+ Hits 2311 2317 +6
+ Misses 646 641 -5
+ Partials 86 85 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
btw @aklinker1, I notice that we don't collect CSS files in public path and the scripts eligible for |
|
Thanks for helping make WXT better! |
@nickbar01234 I'm against making assumptions to generate That said, I could see a feature like this being useful. Feel free to implement if you'd like: #536 (comment) |
gotcha. Is anyone actively working on #544? The issue you referenced seems like it can be bundled as part of the issue |
|
Actually, nevermind. After looking at #544 again, I don't think I want to add these features. It might seem convenient at first, but managing all these global options (permissions, web accessible resources) in one place keeps things simple. If they're spread all over the place, you have to look everywhere for them - imagine removing a permission from one entrypoint, forgetting to remove it from another. Seems like it will cause bugs and tech debt... I think having them in one place is the right move. And thinking about it more, a So I'm actually gonna close #544 as not planned, sorry about that. |
…` option (#2142) Co-authored-by: nickbar01234 <nickbar01234gmail.com> Co-authored-by: Aaron <aaronklinker1@gmail.com>
Overview
Previously,
browser.script.executeScript({ files: [] })does not provide any type hint about what file paths are injectable. This PR augments the type definition to allScriptPublicPath, generated frompath.d.ts.A couple of notes
ScriptPublicPathunion is wider than what can be provided toexecuteScript. The worst case is we run into runtime errors, which is similar to the state before this change.Manual Testing
Related Issue
This PR closes #<issue_number>