Skip to content

Commit

Permalink
chore!: migrate to typescript
Browse files Browse the repository at this point in the history
- also fixes for eslint 9 release
- update eslint and node versions supported
- use pnpm as primary package manager
- exports are from dist because of build step
  • Loading branch information
Yash-Singh1 committed Jan 2, 2024
1 parent 15323fd commit 6828add
Show file tree
Hide file tree
Showing 55 changed files with 803 additions and 579 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ package-lock.json
# Code Coverage
.nyc_output/
coverage/

# Build
dist/
2 changes: 1 addition & 1 deletion .gitpod.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
tasks:
- init: npm install
- init: pnpm install
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand Down
22 changes: 17 additions & 5 deletions lib/data/compat-grant.js → lib/data/compat-grant.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { CompatMap, VersionAssertion } from './version-assertion';

// Documentation:
// - Tampermonkey: https://www.tampermonkey.net/documentation.php#_grant
// - Violentmonkey: https://violentmonkey.github.io/api/gm
// - Greasemonkey: https://wiki.greasespot.net/Greasemonkey_Manual:API
const compatMap = {
export const compatMap: CompatMap = {
'GM.addElement': [
{ type: 'tampermonkey', versionConstraint: '>=4.11.6113' },
{ type: 'violentmonkey', versionConstraint: '>=2.13.0-beta.3' }
Expand Down Expand Up @@ -204,7 +206,20 @@ const compatMap = {
'window.onurlchange': [{ type: 'tampermonkey', versionConstraint: '>=4.11' }]
};

const gmPolyfillOverride = {
export const gmPolyfillOverride: {
[Key in keyof typeof compatMap]?:
| 'ignore'
| {
deps: (keyof typeof compatMap)[];
versions: VersionAssertion[];
}
| {
deps: (keyof typeof compatMap)[];
}
| {
versions: VersionAssertion[];
};
} = {
GM_addStyle: 'ignore',
GM_registerMenuCommand: 'ignore',
GM_getResourceText: {
Expand Down Expand Up @@ -251,6 +266,3 @@ const gmPolyfillOverride = {
deps: ['GM_getResourceText']
}
};

module.exports.compatMap = compatMap;
module.exports.gmPolyfillOverride = gmPolyfillOverride;
10 changes: 7 additions & 3 deletions lib/data/compat-headers.js → lib/data/compat-headers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { CompatMap } from './version-assertion';

// Documentation:
// - Tampermonkey: https://www.tampermonkey.net/documentation.php
// - Violentmonkey: https://violentmonkey.github.io/api/metadata-block/
// - Greasemonkey: https://wiki.greasespot.net/Metadata_Block
const compatMap = {
export const compatMap: {
localized: CompatMap;
unlocalized: CompatMap;
nonFunctional: CompatMap;
} = {
localized: {
name: [
{ type: 'tampermonkey', versionConstraint: '>=3.9' },
Expand Down Expand Up @@ -186,5 +192,3 @@ const compatMap = {
developer: []
}
};

module.exports = compatMap;
8 changes: 8 additions & 0 deletions lib/data/version-assertion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type VersionAssertion = {
type: 'tampermonkey' | 'violentmonkey' | 'greasemonkey';
versionConstraint: string;
};

export type CompatMap = {
[Key in string]?: VersionAssertion[];
};
46 changes: 0 additions & 46 deletions lib/index.js

This file was deleted.

77 changes: 77 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict';

import alignAttributes from './rules/align-attributes';
import betterUseMatch from './rules/better-use-match';
import compatGrant from './rules/compat-grant';
import compatHeaders from './rules/compat-headers';
import filenameUser from './rules/filename-user';
import metadataSpacing from './rules/metadata-spacing';
import noInvalidGrant from './rules/no-invalid-grant';
import noInvalidHeaders from './rules/no-invalid-headers';
import noInvalidMetadata from './rules/no-invalid-metadata';
import requireAttributeSpacePrefix from './rules/require-attribute-space-prefix';
import requireDescription from './rules/require-description';
import requireDownloadUrl from './rules/require-download-url';
import requireName from './rules/require-name';
import requireVersion from './rules/require-version';
import useHomepageAndUrl from './rules/use-homepage-and-url';
import type { ESLint } from 'eslint';

const rules = Object.fromEntries(
Object.entries({
'align-attributes': alignAttributes,
'better-use-match': betterUseMatch,
'compat-grant': compatGrant,
'compat-headers': compatHeaders,
'filename-user': filenameUser,
'metadata-spacing': metadataSpacing,
'no-invalid-grant': noInvalidGrant,
'no-invalid-headers': noInvalidHeaders,
'no-invalid-metadata': noInvalidMetadata,
'require-attribute-space-prefix': requireAttributeSpacePrefix,
'require-description': requireDescription,
'require-download-url': requireDownloadUrl,
'require-name': requireName,
'require-version': requireVersion,
'use-homepage-and-url': useHomepageAndUrl
}).map(([ruleName, ruleMeta]) => {
return [
ruleName,
{
...ruleMeta,
meta: {
...ruleMeta.meta,
docs: {
...ruleMeta.meta.docs,
url: `https://yash-singh1.github.io/eslint-plugin-userscripts/#/rules/${ruleName}`
}
}
}
];
})
) satisfies ESLint.Plugin['rules'];

const configs = {
recommended: {
plugins: ['userscripts'],
rules: {
'userscripts/filename-user': ['error', 'always'],
'userscripts/no-invalid-metadata': ['error', { top: 'required' }],
'userscripts/require-name': ['error', 'required'],
'userscripts/require-description': ['error', 'required'],
'userscripts/require-version': ['error', 'required'],
'userscripts/require-attribute-space-prefix': 'error',
'userscripts/use-homepage-and-url': 'error',
'userscripts/require-download-url': 'error',
'userscripts/align-attributes': ['error', 2],
'userscripts/metadata-spacing': ['error', 'always'],
'userscripts/no-invalid-headers': 'error',
'userscripts/no-invalid-grant': 'error',
'userscripts/compat-grant': 'off',
'userscripts/compat-headers': 'off',
'userscripts/better-use-match': 'warn'
}
}
} satisfies ESLint.Plugin['configs'];

export { rules, configs };
47 changes: 31 additions & 16 deletions lib/rules/align-attributes.js → lib/rules/align-attributes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
module.exports = {
import type { Rule } from 'eslint';
import type { Position } from 'estree';
import type { NonNullishComment } from '../utils/comment';

export default {
meta: {
type: 'suggestion',
docs: {
Expand All @@ -20,18 +24,23 @@ module.exports = {
create: (context) => {
const spacing = context.options[0] || 2;

const sourceCode = context.getSourceCode();
const sourceCode = context.sourceCode;
const comments = sourceCode.getAllComments();

let inMetadata = false;
let done = false;
let metadata = [];
let start = {};
let end = {};
let metadata: {
key: string;
space: number;
line: number;
comment: (typeof comments)[number];
}[] = [];
let start: Position | null = null;
let end: Position | null = null;

for (const comment of comments.filter(
(comment) => comment.type === 'Line'
)) {
(comment) => comment.type === 'Line' && comment.loc
) as NonNullishComment[]) {
if (done) {
continue;
}
Expand All @@ -47,10 +56,10 @@ module.exports = {
inMetadata = true;
} else if (inMetadata && commentValue.startsWith('@')) {
// Get space string between key and value
const [, spaceString] = /^\S*(\s*)/.exec(commentValue.slice(1));
const spaceString = /^\S*(\s*)/.exec(commentValue.slice(1))?.[1];

// Keys w/o value must not be validated
if (spaceString.length === 0) {
if (!spaceString || spaceString.length === 0) {
continue;
}

Expand All @@ -63,7 +72,7 @@ module.exports = {
}
}

if (Object.keys(end).length === 0) {
if (!end) {
end = sourceCode.getLocFromIndex(sourceCode.getText().length);
}

Expand All @@ -78,10 +87,10 @@ module.exports = {
metadata.map(({ space }) => space).sort()[0] < spacing;

if (
hasSpaceLessThenSpacing ||
metadata
.map(({ key, space }) => key.length + space)
.some((val) => val !== totalSpacing)
start &&
end &&
(hasSpaceLessThenSpacing ||
metadata.some(({ key, space }) => key.length + space !== totalSpacing))
) {
context.report({
loc: {
Expand All @@ -99,7 +108,13 @@ module.exports = {
) {
const startColumn = /^(.*?@\S*)/.exec(
sourceCode.getLines()[metadatapoint.line - 1]
)[1].length;
)?.[1].length;

// istanbul ignore if
if (!startColumn) {
continue;
}

fixerRules.push(
fixer.replaceTextRange(
[
Expand All @@ -124,4 +139,4 @@ module.exports = {

return {};
}
};
} satisfies Rule.RuleModule;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const createValidator = require('../utils/createValidator');
import { createValidator } from '../utils/createValidator';

module.exports = createValidator({
export default createValidator({
name: 'include',
required: false,
validator: ({ attrVal, context }) => {
Expand Down
Loading

0 comments on commit 6828add

Please sign in to comment.