3

About

Tired of writing out userscript headers by hand? Of small typos in your @match headers leading to wasted time? Generate Headers to the rescue: this utility package automates header generation for popular userscript managers like Tampermonkey, Violentmonkey, and Greasemonkey.

Most of the information is sourced from your package.json file (on an off-chance you are unfamiliar, here are the NPM docs), and some headers you provide explicitly to either the CLI interface or the programmatic API (like @grant or @match).

Usage example

CLI usage:

generate-headers tampermonkey \
    -m "https://*.stackexchange.com/*" \
    -o "dist/headers.txt" \
    -g get set delete

Programmatic usage as a module:

import { generate } from "@userscripters/generate-headers";

const content = await generate("greasemonkey", { 
    direct: true,
    grants: ["get", "set", "delete"],
    matches: ["https://*.stackexchange.com/*"]
});

Example output:

// ==UserScript==
// @author          Oleg Valter <oleg.a.valter@gmail.com>
// @description     Brings back 404 pages to Stack Exchange network
// @grant           GM_deleteValue
// @grant           GM_getValue
// @grant           GM_listValues
// @grant           GM_setValue
// @homepage        https://github.com/userscripters/bring-back-404#readme
// @match           https://*.askubuntu.com/*
// @match           https://*.mathoverflow.net/*
// @match           https://*.serverfault.com/*
// @match           https://*.stackapps.com/*
// @match           https://*.stackexchange.com/*
// @match           https://*.stackoverflow.com/*
// @name            bring-back-404
// @namespace       userscripters
// @source          git+https://github.com/userscripters/bring-back-404.git
// @supportURL      https://github.com/userscripters/bring-back-404/issues
// @version         0.9.0
// ==/UserScript==

License

The script is licensed under the GPL-3.0-or-later license.

Download

The package is published as both an NPM package and a GitHub package. Can be installed via a package manager like NPM as usual:

npm install --save-dev @userscripters/generate-headers

If you opt to install it from the GitHub registry, please note that it only supports scoped packages, you will need a simple .npmrc file at your project root:

@userscripters:registry=https://npm.pkg.github.com

You will also need to be logged in to GitHub. An easy way to do so is to have a global .npmrc with your PAT (personal access token) set as an access token:

//npm.pkg.github.com/:_authToken=<your token here>

CLI Usage

The package exposes a CLI interface with the following syntax:

generate-headers <tampermonkey | greasemonkey | violentmonkey> [options]

There are various options one can provide to customize the output:

Long Short Required Default Value Description
output o no ./dist/headers.js file path Creates and populates a file with headers content
package p no ./package.json path to package.json Path to package.json to extract info from
collapse c no false none When using the special match all <template> option value, collapses all *.stackexchange.com site entries into one wildcard match
direct d no false none Directs headers content to standard output
grant g no none valid grants (see section below) generates @grant headers to generate, can be repeated
inject i no page page
content
auto
Adds @inject-into header if generating headers for Violentmonkey, no-op otherwise
match m no - match patterns generates valid @match headers (see details here)
pretty - no - prettify output prettifies outputted headers where possible
run r no start start
end
idle
body
menu
Adds @run-at header (values missing in manager are silently dropped)
spaces s no 4 indentation number of spaces to indent header values with (total will be the longest header name + this value)

Some options accept shortcut values for convenience:

Long Value Description Since
grant all Generates all @grant headers available for the userscript manager v2.5.0
match all [template=https://domain/*] Fetches current list of the Stack Exchange network sites and generates @match headers according to the template. The latter must contain the word domain — it will be replaced with site domain for each of the generated entries. v2.7.3

Special pretty option improved the generated output while preserving backwards compatibility:

Header Description Since Example
name Splits the package name on - and capitalizes words 2.6.0 "generate-headers" -> "Generate Headers"

Valid grants

To use some of the sensitive functions exposed by userscript managers, you have to add a @grant header for each of those you use. Generate Headers standardizes and simplifies the process for you (with static analysis of your code coming soon). In both CLI and programmatic API, you can provide multiple grant values (i.e. set), and the package will generate appropriate headers:

Value Tampermonkey Greasemonkey Violentmonkey
set GM_setValue GM.setValue GM_setValue
get GM_getValue GM.getValue GM_getValue
delete GM_deleteValue GM.deleteValue GM_deleteValue
list GM_listValues GM.listValues GM_listValues
unsafe unsafeWindow unsafeWindow unsafeWindow
change window.onurlchange - -
close window.close - window.close
focus window.focus - window.focus
notify - GM.notification GM_notification
clip - GM.setClipboard GM_setClipboard
fetch - GM.xmlHttpRequest GM_xmlhttpRequest (yes, h)
style - - GM_addStyle

Common and manager-specific headers

There are headers common to all userscript managers - for these, the package will source the values from your package.json file and convert the information into headers:

Common headers

Header Package field Required Description Example
@author author yes Author of the userscript. Parses both string and object patterns Oleg Valter oleg.a.valter@gmail.com
@contributors contributors no Contributors to the userscript. Greasemonkey will warn, but we believe contributors must always be listed Double Beep
@description description yes Description of the userscript Userscript manager header generator
@icon icon no Icon of the userscript https://example.com/icon.svg
@name name yes Name of the userscript (for scoped packages - value after the /) generate-headers
@namespace name no Namespace of the userscript - only present for scoped packages userscripters
@version version yes Version of the userscript (will be validated for correctness) 2.1.0

Tampermonkey headers

Header Package field Required Description Example
@homepage homepage no (^2.5) Homepage of the userscript https://github.com/userscripters/generate-headers#readme
@supportURL bugs.url no (^2.5) Where to report issues https://github.com/userscripters/generate-headers/issues
@source repository.url no (^2.5) Where to find the source code git+https://github.com/userscripters/generate-headers.git

Violentmonkey headers

Header Package field Required Description Example
@homepageURL homepage no (^2.5) Homepage of the userscript https://github.com/userscripters/generate-headers#readme
@supportURL bugs.url no (^2.5) Where to report issues https://github.com/userscripters/generate-headers/issues

Field and header validation

Since v2.0.0, the package validates @match headers according to the rules specified here (and that userscript managers follow). Providing incorrect values will result in an error message and dropping of those headers from the output:

invalid @match header value console message

Since v2.3.0, Generate Headers also checks the presence of required fields in package.json, as well as validates some of them for correctness. Contrary to the above, failing validation of these headers results in early termination, so no output will be generated:

Field Validation
author must be present
description must be present
name must be present
homepage homepage URL must be a valid URL
version the version must be a valid semver version

And here is an output if the package.json has major issues:

example output failing validation

Platform

This is a Node.js package (tested on LTS 14.9.0), so it requires Node to be installed. Best used with TypeScript, but contains type declaration files for autocompletion as well.

Contact

Author: Oleg Valter
Organization: UserScripters

Please, submit bug reports on the source repository.
Before adding a new one, please check if it hasn't been raised before.

You can also drop by to chat, we are a friendly bunch.

Code

Source code is written in TypeScript.

Contributions are welcome, you can always submit a PR here.

3
  • 1
    It is worth mentioning that you need a somewhat complete package.json. I had one without a "name" and then the error message is far from helpful.
    – rene
    Aug 11 at 18:42
  • @rene yup, I only recently added required fields validation, but didn't have enough time to spare to add more descriptive error message for the validation - coming soon! I tried to outline the "required" fields as best as I could in the docs here, for now, though (column "required"). Also, I plan to add granular override options for v3.0.0 Aug 11 at 18:50
  • P.s. if you make it as a feature request to make validation messages more helpful, I will gladly fulfill it as soon as I can - the next iteration brings in Violentmonkey headers, and as soon as that's done, I can shift to making the package more feature-rich Aug 11 at 18:57
1

The package.json needs to exist and the required properties need to have a value. While it is documented it is easily overlooked.

My use case is slightly different. I wanted to generate headers for userscripts I have written over the years and those don't have a package.json and I wasn't planning on adding one.

I prefer the error message is more clear about what is missing and where. So instead of "cannot read property 'match' of undefined" I'd rather see: "The name property is missing from the package.json" but an alternative could be to offer a reasonable default. That would work for my use case.

3
  • 1
    done and soon will be published - small preview for missing properties Aug 11 at 20:00
  • Done and published - best consumed starting v2.5.0 (latest) - I connected the required fields to validators and made prettier console logs for each of them (+for those fields that have special validation), as well as reduced the number of required fields to author, description, name, and version (as you will need them in any case). Please, add [status-completed] when (and if) you are able to confirm that the request is granted :) On an off-note, the next major version will expose the required fields to user overrides so as you don't even have to have a package.json to run it. Aug 12 at 0:43
  • The reason why the initial version relied heavily on a valid package.json is that it was intended to be an internal package for the org integrated into automated versioning system, but since the project kept growing, I decided to make it a proper library useful to everyone :) Oh, before I forget - the package is now available as both NPM package and GitHub package Aug 12 at 0:45
1

I would like an option to have the generator expand a single match argument to all known Stack Exchange domains.

So for example -m "https://*.stackexchange.com/reviews/*" -all results in

// @match           https://*.askubuntu.com/reviews/*
// @match           https://*.mathoverflow.net/reviews/*
// @match           https://*.serverfault.com/reviews/*
// @match           https://*.stackapps.com/reviews/*
// @match           https://*.stackexchange.com/reviews/*
// @match           https://*.superuser.com/reviews/*
// @match           https://*.stackoverflow.com/reviews/*

I can imagine being able to include/exclude chat would be useful but nice to have for now.

2
  • Agree - I have @include / @exclude headers is also coming soon - the workload is just a bit too much to handle at the same time :) As for the expansion to all stackexchange domains - good idea, thank you, added to the list of features to add! Aug 11 at 19:31
  • status-completed - version 2.7.3 extends the --match option with a special syntax --match all [template] where template is a valid match with a word domain in it (it is used to map sites to custom custom paths). If only all is provided, a https://domain/* will be used. --collapse option controls if stackexchange.com sites will be put under *.stackexchange.com or exploded individually. I am still experimenting with the default value, though, for now it is set to false, but it is probably a good idea to switch to true as a more intuitive option. 2 days ago

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .