webext-schema 6.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13
+ custom: ['https://paypal.me/asamuzakjp'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -0,0 +1,31 @@
1
+ # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
+
4
+ name: build
5
+ permissions:
6
+ contents: read
7
+
8
+ on:
9
+ push:
10
+ branches: [ main ]
11
+ pull_request:
12
+ branches: [ main ]
13
+ release:
14
+ types: [ created ]
15
+
16
+ jobs:
17
+ build:
18
+ strategy:
19
+ matrix:
20
+ node-version: [ 22.x, lts/*, latest ]
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+ - name: Use Node.js ${{ matrix.node-version }}
25
+ uses: actions/setup-node@v6
26
+ with:
27
+ node-version: ${{ matrix.node-version }}
28
+ check-latest: true
29
+ - run: npm ci
30
+ - run: npm run lint
31
+ - run: npm run test:all
package/README.md CHANGED
@@ -1,11 +1,19 @@
1
+ # webext-schema
2
+
1
3
  [![build](https://github.com/asamuzaK/webext-schema/workflows/build/badge.svg)](https://github.com/asamuzaK/webext-schema/actions?query=workflow%3Abuild)
2
4
  [![CodeQL](https://github.com/asamuzaK/webext-schema/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/asamuzaK/webext-schema/actions/workflows/github-code-scanning/codeql)
3
5
  [![npm](https://img.shields.io/npm/v/webext-schema)](https://www.npmjs.com/package/webext-schema)
4
6
 
5
- # webext-schema
7
+ [WebExtensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions "Browser Extensions - Mozilla | MDN") schemas and [MailExtensions](https://developer.thunderbird.net/add-ons/mailextensions "A Guide to Extensions - Thunderbird") schemas fetched from [hg.mozilla.org](https://hg.mozilla.org/).
8
+ Stubbed browser API and a standalone browser utility script are also available.
9
+
10
+ ## Features
6
11
 
7
- [WebExtentions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions "Browser Extensions - Mozilla | MDN") schemas and [MailExtensions](https://developer.thunderbird.net/add-ons/mailextensions "A Guide to Extensions - Thunderbird") schemas fetched from [hg.mozilla.org](https://hg.mozilla.org/).
8
- Stubbed browser API is also available.
12
+ * **Up-to-date Schemas:** Directly fetched from Mozilla's repositories.
13
+ * **Multi-Channel Support:** Choose between `beta`, `central`, and `mail` channels to match your target environment.
14
+ * **Easy API Mocking:** Instantly generate a stubbed `browser` object powered by [Sinon.JS](https://sinonjs.org/) for robust unit testing of your extensions.
15
+ * **Standalone Utility Included:** Comes with `browser.js`, a dependency-free, Promise-wrapped utility script ready to be dropped into your extension project for easier API handling.
16
+ * **Modern ESM & TypeScript:** Native ES Modules support with bundled TypeScript definitions (`index.d.ts`).
9
17
 
10
18
  ## Install
11
19
 
@@ -13,7 +21,7 @@ Stubbed browser API is also available.
13
21
  npm i webext-schema
14
22
  ```
15
23
 
16
- ## Usage
24
+ ## Usage (Schema & Mock)
17
25
 
18
26
  ```javascript
19
27
  import { Schema } from 'webext-schema';
@@ -23,7 +31,7 @@ const schema = new Schema();
23
31
 
24
32
  ### new Schema(<var>channel</var>, <var>sinonConfig</var>)
25
33
 
26
- * @param {string} [channel] - release channel. one of "beta", "central", "release", "esr", "mail".
34
+ * @param {string} [channel] - release channel. one of "beta", "central", "mail".
27
35
  * @param {Object} [sinonConfig] - optional configuration for `sinon.createSandbox()`, see [Sinon.JS](https://sinonjs.org/) for details.
28
36
 
29
37
  Both arguments are optional.
@@ -37,7 +45,7 @@ const schema = new Schema("central", {
37
45
 
38
46
  ### schema.channel
39
47
 
40
- "central", "beta", "release", "esr" for WebExtensions, and "mail" for MailExtensions are available.
48
+ "central", "beta" for WebExtensions, and "mail" for MailExtensions are available.
41
49
  Channel defaults to "beta".
42
50
 
43
51
  ```javascript
@@ -125,3 +133,26 @@ assert.isFunction(port2.onDisconnect.addListener);
125
133
  // reset
126
134
  browser._sandbox.reset();
127
135
  ```
136
+
137
+ ---
138
+
139
+ ## Browser Utility (`browser.js`)
140
+
141
+ A standalone utility script (`browser.js`) is also included in this repository. It provides useful, Promise-wrapped functions for common browser extension APIs (e.g., `browser.tabs`, `browser.runtime`, `browser.storage`).
142
+
143
+ This file is designed to be copied directly into your browser extension project. It has no external dependencies and works natively in your background or content scripts.
144
+
145
+ ### How to use `browser.js`
146
+
147
+ 1. Copy `browser.js` from the `webext-schema` repository into your extension's source directory.
148
+ 2. Import the needed functions into your extension scripts:
149
+
150
+ ```javascript
151
+ import { createTab, getActiveTab, setStorage } from './path/to/browser.js';
152
+
153
+ // Example: Create a new tab and save data
154
+ async function openAndSave() {
155
+ const tab = await createTab({ url: '[https://example.com](https://example.com)' });
156
+ await setStorage({ lastOpenedTabId: tab.id }, 'local');
157
+ }
158
+ ```
package/SECURITY.md ADDED
@@ -0,0 +1,36 @@
1
+ # Security Policy
2
+
3
+ We take security vulnerabilities seriously. Thank you for improving the security of our project.
4
+
5
+ ## Supported Versions
6
+
7
+ The following versions of this project are currently supported with security updates:
8
+
9
+ | Version | Supported |
10
+ | ------- | ------------------ |
11
+ | 7.x.x | :white_check_mark: |
12
+ | 6.x.x | :white_check_mark: |
13
+ | < 6.0.0 | :x: |
14
+
15
+ ## Reporting a Vulnerability
16
+
17
+ Please **DO NOT** open a public issue for security-related vulnerabilities.
18
+
19
+ If you discover a security vulnerability, please report it privately via **GitHub's Private vulnerability reporting** feature.
20
+ You can do this by navigating to the **Security** tab of this repository, selecting **Advisories**, and clicking the **Report a vulnerability** button.
21
+
22
+ To help us resolve the issue efficiently, please include the following details in your report:
23
+
24
+ * **Type of vulnerability** (e.g., XSS, SSRF, Prototype Pollution)
25
+ * **Affected component or file name**
26
+ * **Steps to reproduce** (including proof of concept / PoC code if available)
27
+ * **Potential impact** of the vulnerability
28
+
29
+ ### Our Response Process
30
+
31
+ 1. **Acknowledgment**: We will acknowledge receipt of your report within 48 to 72 hours.
32
+ 2. **Investigation**: We will verify the vulnerability and evaluate its severity.
33
+ 3. **Fix & Release**: We will work on a fix in a private fork and release a patched version as soon as possible.
34
+ 4. **Advisory**: A GitHub Security Advisory will be published if necessary, giving you full credit for the discovery (unless you prefer to remain anonymous).
35
+
36
+ Please adhere to Coordinated Vulnerability Disclosure (CVD) and **do not disclose the vulnerability publicly** until a patch has been released.
@@ -0,0 +1,46 @@
1
+ import jsdoc from 'eslint-plugin-jsdoc';
2
+ import regexp from 'eslint-plugin-regexp';
3
+ import unicorn from 'eslint-plugin-unicorn';
4
+ import globals from 'globals';
5
+ import neostandard, { plugins as neostdplugins } from 'neostandard';
6
+
7
+ export default [
8
+ ...neostandard({
9
+ semi: true
10
+ }),
11
+ jsdoc.configs['flat/recommended'],
12
+ regexp.configs['flat/recommended'],
13
+ {
14
+ languageOptions: {
15
+ globals: {
16
+ ...globals.browser,
17
+ ...globals.node,
18
+ ...globals.webextensions
19
+ }
20
+ },
21
+ linterOptions: {
22
+ reportUnusedDisableDirectives: true
23
+ },
24
+ plugins: {
25
+ '@stylistic': neostdplugins['@stylistic'],
26
+ regexp,
27
+ unicorn
28
+ },
29
+ rules: {
30
+ '@stylistic/space-before-function-paren': ['error', {
31
+ anonymous: 'always',
32
+ asyncArrow: 'always',
33
+ named: 'never'
34
+ }],
35
+ 'no-await-in-loop': 'error',
36
+ 'no-use-before-define': ['error', {
37
+ allowNamedExports: false,
38
+ classes: true,
39
+ functions: true,
40
+ variables: true
41
+ }],
42
+ 'prefer-object-has-own': 'error',
43
+ 'unicorn/prefer-node-protocol': 'error'
44
+ }
45
+ }
46
+ ];
package/index.js CHANGED
@@ -9,11 +9,17 @@
9
9
  /* api */
10
10
  import process from 'node:process';
11
11
  import { parseCommand } from './modules/commander.js';
12
- import { logErr, throwErr } from './modules/common.js';
13
12
  export { Schema } from './modules/schema.js';
14
13
 
15
14
  /* process */
16
- process.on('uncaughtException', throwErr);
17
- process.on('unhandledRejection', logErr);
15
+ process.on('uncaughtException', err => {
16
+ console.error('Fatal Error (Uncaught Exception):', err);
17
+ process.exit(1);
18
+ });
19
+
20
+ process.on('unhandledRejection', reason => {
21
+ console.error('Fatal Error (Unhandled Rejection):', reason);
22
+ process.exit(1);
23
+ });
18
24
 
19
25
  parseCommand(process.argv);
@@ -2,12 +2,48 @@
2
2
  * browser.js
3
3
  */
4
4
 
5
- /* shared */
6
- import { getType, isObjectNotEmpty, isString, logErr } from './common.js';
7
-
8
5
  /* api */
9
6
  const { permissions, runtime, tabs, windows } = browser;
10
7
 
8
+ /* constants & utils */
9
+ const TYPE_FROM = 8;
10
+ const TYPE_TO = -1;
11
+
12
+ /**
13
+ * log error
14
+ * @param {!object} e - Error
15
+ * @returns {boolean} - false
16
+ */
17
+ const logErr = e => {
18
+ console.error(e);
19
+ return false;
20
+ };
21
+
22
+ /**
23
+ * get type
24
+ * @param {object} o - object to check
25
+ * @returns {string} - type of object
26
+ */
27
+ const getType = o =>
28
+ Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);
29
+
30
+ /**
31
+ * is object, and not an empty object
32
+ * @param {object} o - object to check;
33
+ * @returns {boolean} - result
34
+ */
35
+ const isObjectNotEmpty = o => {
36
+ const items = /Object/i.test(getType(o)) && Object.keys(o);
37
+ return !!(items?.length);
38
+ };
39
+
40
+ /**
41
+ * is string
42
+ * @param {object} o - object to check
43
+ * @returns {boolean} - result
44
+ */
45
+ const isString = o => typeof o === 'string' || o instanceof String;
46
+
11
47
  /**
12
48
  * check if permission is granted
13
49
  * @param {object} perm - permissions.Permission
package/modules/schema.js CHANGED
@@ -22,14 +22,13 @@ export class Schema {
22
22
  * construct
23
23
  * @param {...(string|object)} [args] - optional arguments
24
24
  * {string} - release channel.
25
- * one of "beta", "central",
26
- * "esr", "mail".
25
+ * "beta", "central", "mail".
27
26
  * {object} - sinon config
28
27
  */
29
28
  constructor(...args) {
30
29
  const [arg1, arg2] = args;
31
30
  this.#channel =
32
- isString(arg1) && /(?:centra|mai)l|beta|esr/.test(arg1)
31
+ isString(arg1) && /^(?:central|mail)$/.test(arg1)
33
32
  ? arg1
34
33
  : 'beta';
35
34
  this._sandbox =
@@ -48,7 +47,7 @@ export class Schema {
48
47
  }
49
48
 
50
49
  set channel(ch) {
51
- if (isString(ch) && /(?:centra|mai)l|beta|esr/.test(ch)) {
50
+ if (isString(ch) && /^(?:central|mail|beta)$/.test(ch)) {
52
51
  this.#channel = ch;
53
52
  }
54
53
  }
package/modules/update.js CHANGED
@@ -14,7 +14,6 @@ import { createFile } from './file-util.js';
14
14
  import { CHAR, INDENT } from './constant.js';
15
15
  const DIR_CWD = process.cwd();
16
16
  const PERM_FILE = 0o644;
17
- export const ESR_VER = 115;
18
17
 
19
18
  /**
20
19
  * fetch text
@@ -45,9 +44,6 @@ export const getChannelUrl = channel => {
45
44
  case 'central':
46
45
  dir = 'mozilla-central/';
47
46
  break;
48
- case 'esr':
49
- dir = `releases/mozilla-esr${ESR_VER}/`;
50
- break;
51
47
  case 'mail':
52
48
  dir = 'comm-central/';
53
49
  break;
@@ -274,7 +270,6 @@ export const updateSchemas = async (cmdOpts = {}) => {
274
270
  func.push(
275
271
  saveSchemaFile('beta', info),
276
272
  saveSchemaFile('central', info),
277
- saveSchemaFile('esr', info),
278
273
  saveSchemaFile('mail', info)
279
274
  );
280
275
  }
package/package.json CHANGED
@@ -11,51 +11,60 @@
11
11
  },
12
12
  "type": "module",
13
13
  "exports": {
14
- "default": {
14
+ ".": {
15
15
  "types": "./types/index.d.ts",
16
16
  "default": "./index.js"
17
- }
17
+ },
18
+ "./package.json": "./package.json"
18
19
  },
19
- "types": "types/index.d.ts",
20
20
  "dependencies": {
21
21
  "camelize": "^1.0.1",
22
- "commander": "^14.0.1",
22
+ "commander": "^15.0.0",
23
23
  "decamelize": "^6.0.1",
24
24
  "json5": "^2.2.3",
25
- "sinon": "^21.0.0"
25
+ "sinon": "^22.1.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@types/firefox-webext-browser": "^120.0.5",
29
- "@types/node": "^24.6.2",
30
- "@types/sinon": "^17.0.4",
31
- "c8": "^10.1.3",
32
- "eslint": "^9.37.0",
33
- "eslint-plugin-jsdoc": "^60.8.0",
34
- "eslint-plugin-regexp": "^2.10.0",
35
- "eslint-plugin-unicorn": "^61.0.2",
36
- "globals": "^16.4.0",
37
- "mocha": "^11.7.4",
38
- "neostandard": "^0.12.2",
39
- "npm-run-all2": "^8.0.4",
40
- "typescript": "^5.9.3",
41
- "undici": "^7.16.0"
28
+ "@types/firefox-webext-browser": "^143.0.0",
29
+ "@types/node": "^26.1.1",
30
+ "@types/sinon": "^22.0.0",
31
+ "c8": "^12.0.0",
32
+ "eslint": "^9.39.5",
33
+ "eslint-plugin-jsdoc": "^63.2.2",
34
+ "eslint-plugin-regexp": "^3.1.1",
35
+ "eslint-plugin-unicorn": "^64.0.0",
36
+ "globals": "^17.7.0",
37
+ "mocha": "^11.7.6",
38
+ "neostandard": "^0.13.0",
39
+ "typescript": "^7.0.2",
40
+ "undici": "^8.9.0"
41
+ },
42
+ "overrides": {
43
+ "c8": {
44
+ "yargs": "^18.0.0"
45
+ },
46
+ "eslint": {
47
+ "js-yaml": "^4.3.0"
48
+ },
49
+ "mocha": {
50
+ "diff": "^8.0.3",
51
+ "js-yaml": "^4.3.0"
52
+ },
53
+ "serialize-javascript": "^7.0.4"
42
54
  },
43
55
  "scripts": {
44
56
  "build": "npm run tsc && npm run lint && npm run test",
45
57
  "lint": "eslint . --fix",
46
58
  "start": "node index",
47
59
  "test": "npm run test:central",
60
+ "test:all": "npm run test:beta && npm run test:central",
48
61
  "test:beta": "c8 mocha --require=test/mocha/setup.js --channel=beta --exit test/*.test.js",
49
62
  "test:central": "c8 mocha --require=test/mocha/setup.js --channel=central --exit test/*.test.js",
50
- "test:esr": "c8 mocha --require=test/mocha/setup.js --channel=esr --exit test/*.test.js",
51
- "test:release": "c8 mocha --require=test/mocha/setup.js --channel=release --exit test/*.test.js",
52
- "testall": "npm-run-all -s test:*",
53
63
  "tsc": "node index clean --dir=types -i && npx tsc",
54
- "update": "node index update -i",
64
+ "update": "npm run update:beta && npm run update:central && npm run update:mail",
55
65
  "update:beta": "node index update --channel=beta -i",
56
66
  "update:central": "node index update --channel=central -i",
57
- "update:esr": "node index update --channel=esr -i",
58
67
  "update:mail": "node index update --channel=mail -i"
59
68
  },
60
- "version": "6.0.0"
69
+ "version": "7.1.0"
61
70
  }