{"id":20396872,"url":"https://github.com/bpevs/bext","last_synced_at":"2025-04-12T12:51:16.611Z","repository":{"id":41545927,"uuid":"503861687","full_name":"bpevs/bext","owner":"bpevs","description":"Tools for Deno-Powered Web Extensions","archived":false,"fork":false,"pushed_at":"2025-01-08T13:47:06.000Z","size":214,"stargazers_count":43,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-26T07:36:18.498Z","etag":null,"topics":["deno","webextensions"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bpevs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-15T17:28:04.000Z","updated_at":"2025-01-25T15:55:44.000Z","dependencies_parsed_at":"2024-07-23T06:37:48.504Z","dependency_job_id":null,"html_url":"https://github.com/bpevs/bext","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"a9152556d0ee08201d96943453e910e3afa2d8b8"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpevs%2Fbext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpevs%2Fbext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpevs%2Fbext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpevs%2Fbext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpevs","download_url":"https://codeload.github.com/bpevs/bext/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248571364,"owners_count":21126517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","webextensions"],"created_at":"2024-11-15T04:10:08.055Z","updated_at":"2025-04-12T12:51:16.605Z","avatar_url":"https://github.com/bpevs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bext\n\nTools for Building [Browser Extensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions) with Deno. Supports Chromium and Firefox browsers.\n\n# Usage\n\nYou can see basic examples here: https://github.com/bpevs/bext/tree/main/examples\n\nYou can also see a real-world example by looking at [Favioli](https://github.com/bpevs/favioli).\n\n## Bundle\n\nOnce you have an app structured, bext can bundle your extension for Chrome and Firefox using esbuild. It will also take browser-specific properties from your\n`manifest.json` file, and format them into a compatible structure for each\nbrowser.\n\n```sh\n\u003e deno install -gA --name=bext jsr:@bpev/bext/bin\n\n\u003e cd ./my_project\n\n\u003e bext # both\n\u003e bext chrome # only chrome\n\u003e bext firefox # only ff\n\n# Watch mode\n\u003e bext --watch # or -w: build again on change\n\u003e bext chrome -w # variations can be used for single-platform\n\u003e bext firefox --watch\n\n# Custom directories\n\u003e bext --source=src # --source or -s: specify source directory (default: \"source\")\n\u003e bext --source=src --static=assets # --static or -t: specify static assets directory (default: \"static\")\n\u003e bext --source=src --static=assets --output=build # --output or -o: specify output directory (default: \"dist\")\n\n\u003e bext --config=../deno.json # --config or -c: specify deno.json config file. If using a workspace, point at the root workspace deno.json\n```\n\n## Types and Utilities\n\nWhile building your app, bext re-exports the native extension apis, to smooth out a few of the cross-platform differences. We also add a couple utility functions to determine which browser we are using.\n\n```ts\n// Import the direct npm:@types/chrome import used to define browserAPI in Bext\n// Alternatively, `import { Tab, TabChangeInfo } from npm:@types/chrome`\nimport type Chrome from 'jsr:@bpev/bext/types/chrome'\n\n/**\n * browserAPI resolves to:\n *   - globalThis.chrome in Chromium browsers\n *   - globalThis.browser in Firefox browsers\n *   - Bext's mock_browser in Deno context (for unit testing)\n */\nimport browserAPI, { isChrome, isFirefox } from 'jsr:@bpev/bext'\n\nbrowserAPI.tabs.onUpdated.addListener(\n  (tabId: number, _: Chrome.TabChangeInfo, tab: Chrome.Tab) =\u003e {\n    console.log(isChrome(), isFirefox())\n  },\n)\n```\n\n## Testing\n\nbext `browserAPI` will also return a mock browser when running in a Deno environment (where native extension apis don't exist). This makes writing unit tests a breeze!\n\n```ts\nimport browserAPI, { isDeno } from 'jsr:@bpev/bext'\nimport { assertStrictEquals } from 'jsr:@std/assert'\nimport { assertSpyCall, assertSpyCalls, stub } from 'jsr:@std/testing/mock'\n\nimport { getStorage } from './storage_helpers.ts'\n\nDeno.test('is running in test env', () =\u003e {\n  assert()\n})\n\nDeno.test('uses browser storage', async () =\u003e {\n  const getStorageStub = stub(browserAPI.storage.sync, 'get', () =\u003e {\n    return Promise.resolve({ storage_key: 'mock_storage_value' })\n  })\n\n  assertStrictEquals(await getStorage(), 'mock_storage_value')\n  assertSpyCalls(getStorageStub, 1)\n\n  // Expect `chrome.sync.storage.get` to be called with the storage_key\n  assertSpyCall(getStorageStub, 0, { args: ['storage_key'] })\n  getStorageStub.restore()\n})\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpevs%2Fbext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpevs%2Fbext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpevs%2Fbext/lists"}