init
This commit is contained in:
50
.eslintrc.json
Normal file
50
.eslintrc.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"rules": {
|
||||
"@typescript-eslint/strict-boolean-expressions": [
|
||||
2,
|
||||
{
|
||||
"allowString": false,
|
||||
"allowNumber": false
|
||||
}
|
||||
],
|
||||
|
||||
/* important */
|
||||
"prefer-const": "error",
|
||||
"quotes": ["error", "single"],
|
||||
|
||||
"block-scoped-var": "error",
|
||||
"camelcase": "error",
|
||||
"consistent-this": ["error", "that"],
|
||||
"no-else-return": "error",
|
||||
"no-eq-null": "error",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implicit-coercion": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-invalid-this": "error",
|
||||
"require-await": "error",
|
||||
"yoda": "error",
|
||||
|
||||
"semi": ["error", "always"],
|
||||
"semi-style": ["error", "last"],
|
||||
|
||||
/* less important */
|
||||
"no-unreachable-loop": "error",
|
||||
"no-unused-private-class-members": "error",
|
||||
"no-use-before-define": "error",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-promise-executor-return": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-constructor-return": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"array-callback-return": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error"
|
||||
},
|
||||
"ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
|
||||
}
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@@ -0,0 +1 @@
|
||||
dist/*
|
||||
10
.prettierrc
Normal file
10
.prettierrc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
45
lib/main.js
Normal file
45
lib/main.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import { build } from 'esbuild';
|
||||
import { lstatSync, readdirSync, readFileSync, unlinkSync, writeFileSync, } from 'fs';
|
||||
import { DistBase, DistPath, ScriptBase, ScriptPath } from './paths';
|
||||
import readMeta from './readmeta';
|
||||
async function compileProject(name) {
|
||||
//read meta file
|
||||
let [metaJson, metaString] = readMeta(name);
|
||||
let outPath = DistPath(name);
|
||||
await build({
|
||||
entryPoints: [ScriptPath(name).main],
|
||||
outfile: outPath,
|
||||
target: 'esnext',
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
bundle: true,
|
||||
minify: false,
|
||||
define: {
|
||||
UserScriptName: `'${metaJson.name}'`,
|
||||
UserScriptNamespace: `'${metaJson.namespace}'`,
|
||||
UserScriptVersion: `'${metaJson.version}'`,
|
||||
UserScriptDownloadURL: `'${metaJson.downloadURL}'`,
|
||||
UserScriptSupportURL: `'${metaJson.supportURL}'`,
|
||||
UserScriptHomepageURL: `'${metaJson.homepageURL}'`,
|
||||
},
|
||||
});
|
||||
//add UserScript header
|
||||
let content = readFileSync(outPath).toString();
|
||||
writeFileSync(outPath, metaString + content);
|
||||
}
|
||||
if (!lstatSync('package.json').isFile()) {
|
||||
console.error('package.json not found, unwilling to run');
|
||||
process.exit(1);
|
||||
}
|
||||
//delete compiled scripts
|
||||
readdirSync(DistBase).forEach(file => unlinkSync(`${DistBase}/${file}`));
|
||||
//compile scripts
|
||||
readdirSync(ScriptBase).forEach(name => {
|
||||
let path = ScriptPath(name);
|
||||
if (!name.endsWith('_') &&
|
||||
lstatSync(path.dir).isDirectory() &&
|
||||
lstatSync(path.main).isFile()) {
|
||||
compileProject(name);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=main.js.map
|
||||
1
lib/main.js.map
Normal file
1
lib/main.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EACH,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,GAChB,MAAM,IAAI,CAAA;AACX,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpE,OAAO,QAAQ,MAAM,YAAY,CAAA;AAEjC,KAAK,UAAU,cAAc,CAAC,IAAY;IACtC,gBAAgB;IAChB,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC3C,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAE5B,MAAM,KAAK,CAAC;QACR,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QACpC,OAAO,EAAE,OAAO;QAEhB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,KAAK;QAEb,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QAEb,MAAM,EAAE;YACJ,cAAc,EAAE,IAAI,QAAQ,CAAC,IAAI,GAAG;YACpC,mBAAmB,EAAE,IAAI,QAAQ,CAAC,SAAS,GAAG;YAC9C,iBAAiB,EAAE,IAAI,QAAQ,CAAC,OAAO,GAAG;YAE1C,qBAAqB,EAAE,IAAI,QAAQ,CAAC,WAAW,GAAG;YAClD,oBAAoB,EAAE,IAAI,QAAQ,CAAC,UAAU,GAAG;YAChD,qBAAqB,EAAE,IAAI,QAAQ,CAAC,WAAW,GAAG;SACrD;KACJ,CAAC,CAAA;IAEF,uBAAuB;IACvB,IAAI,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9C,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,CAAA;AAChD,CAAC;AAED,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,EAAE;IACrC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;CAClB;AAED,yBAAyB;AACzB,WAAW,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;AAExE,iBAAiB;AACjB,WAAW,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;IACnC,IAAI,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAE3B,IACI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;QACjC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAC/B;QACE,cAAc,CAAC,IAAI,CAAC,CAAA;KACvB;AACL,CAAC,CAAC,CAAA"}
|
||||
13
lib/paths.js
Normal file
13
lib/paths.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const BaseUrl = `https://git.zomo.dev/zomo/browser-scripts`;
|
||||
export const RemoteBranch = 'main';
|
||||
export const ScriptBase = 'scripts';
|
||||
export const DistBase = 'dist';
|
||||
export const SupportUrl = `${BaseUrl}/issues`;
|
||||
export const FileUrl = (name) => `${BaseUrl}/raw/branch/${RemoteBranch}/${DistBase}/${name}.user.js`;
|
||||
export const ScriptPath = (name) => ({
|
||||
dir: `${ScriptBase}/${name}`,
|
||||
main: `${ScriptBase}/${name}/main.ts`,
|
||||
meta: `${ScriptBase}/${name}/meta.json`,
|
||||
});
|
||||
export const DistPath = (name) => `${DistBase}/${name}.user.js`;
|
||||
//# sourceMappingURL=paths.js.map
|
||||
1
lib/paths.js.map
Normal file
1
lib/paths.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,2CAA2C,CAAA;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AACnC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAA;AAE9B,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,OAAO,SAAS,CAAA;AAC7C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CACpC,GAAG,OAAO,eAAe,YAAY,IAAI,QAAQ,IAAI,IAAI,UAAU,CAAA;AAEvE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC;IACzC,GAAG,EAAE,GAAG,UAAU,IAAI,IAAI,EAAE;IAC5B,IAAI,EAAE,GAAG,UAAU,IAAI,IAAI,UAAU;IACrC,IAAI,EAAE,GAAG,UAAU,IAAI,IAAI,YAAY;CAC1C,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,QAAQ,IAAI,IAAI,UAAU,CAAA"}
|
||||
89
lib/readmeta.js
Normal file
89
lib/readmeta.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { lstatSync, readFileSync } from 'fs';
|
||||
import { BaseUrl, FileUrl, ScriptPath, SupportUrl } from './paths';
|
||||
export default function (name) {
|
||||
var meta = {
|
||||
name: name,
|
||||
namespace: 'zomo.dev',
|
||||
match: '',
|
||||
excludematch: '',
|
||||
version: '0.0.0',
|
||||
description: '',
|
||||
icon: '',
|
||||
require: '',
|
||||
resource: '',
|
||||
runat: '',
|
||||
noframes: false,
|
||||
grant: '',
|
||||
injectinto: '',
|
||||
downloadURL: FileUrl(name),
|
||||
supportURL: SupportUrl,
|
||||
homepageURL: BaseUrl,
|
||||
unwrap: false,
|
||||
};
|
||||
let metaPath = ScriptPath(name).meta;
|
||||
if (lstatSync(metaPath).isFile()) {
|
||||
try {
|
||||
let args = JSON.parse(readFileSync(metaPath).toString());
|
||||
let key;
|
||||
for (key in meta) {
|
||||
let val = args[key];
|
||||
//cases where the value is empty
|
||||
if (val === undefined)
|
||||
continue;
|
||||
if (val === false)
|
||||
continue;
|
||||
if (val === '')
|
||||
continue;
|
||||
meta[key] = val;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log(`${metaPath} not found, using default metadata`);
|
||||
}
|
||||
const keyConversion = {
|
||||
injectinto: 'inject-into',
|
||||
excludematch: 'exclude-match',
|
||||
};
|
||||
return [
|
||||
meta,
|
||||
`// ==UserScript==
|
||||
${Object.keys(meta)
|
||||
.filter(key => {
|
||||
let val = meta[key];
|
||||
if (val === undefined)
|
||||
return false;
|
||||
if (val === false)
|
||||
return false;
|
||||
if (val === '')
|
||||
return false;
|
||||
return true;
|
||||
})
|
||||
.map(key => {
|
||||
let val = meta[key];
|
||||
let key_str = key in keyConversion
|
||||
? keyConversion[key]
|
||||
: key;
|
||||
key_str = key_str.padStart(12, ' ');
|
||||
if (typeof val === 'boolean') {
|
||||
if (val)
|
||||
return `// @${key_str}`;
|
||||
}
|
||||
else if (typeof val === 'string') {
|
||||
return `// @${key_str} ${val}`;
|
||||
}
|
||||
else if (Array.isArray(val)) {
|
||||
return val.map(v => `// @${key_str} ${v}`).join('\n');
|
||||
}
|
||||
return '';
|
||||
})
|
||||
.filter(l => l.length)
|
||||
.join('\n')}
|
||||
// ==/UserScript==
|
||||
`,
|
||||
];
|
||||
}
|
||||
//# sourceMappingURL=readmeta.js.map
|
||||
1
lib/readmeta.js.map
Normal file
1
lib/readmeta.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"readmeta.js","sourceRoot":"","sources":["../src/readmeta.ts"],"names":[],"mappings":"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"}
|
||||
2
lib/types.js
Normal file
2
lib/types.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
lib/types.js.map
Normal file
1
lib/types.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
||||
103
meta.schema.json
Normal file
103
meta.schema.json
Normal file
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "UserScriptMeta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Script Name",
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"description": "Author namespace",
|
||||
"type": "string"
|
||||
},
|
||||
"match": {
|
||||
"description": "",
|
||||
"type": ["string", "array"],
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"excludematch": {
|
||||
"description": "",
|
||||
"type": ["string", "array"],
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"require": {
|
||||
"description": "",
|
||||
"type": ["string", "array"],
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resource": {
|
||||
"description": "",
|
||||
"type": ["string", "array"],
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"runat": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"enum": ["document-start", "document-end", "document-idle"]
|
||||
},
|
||||
"noframes": {
|
||||
"description": "",
|
||||
"type": "boolean"
|
||||
},
|
||||
"grant": {
|
||||
"description": "",
|
||||
"type": ["string", "array"],
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"injectinto": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"enum": ["page", "content", "auto"]
|
||||
},
|
||||
"downloadURL": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"supportURL": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"homepageURL": {
|
||||
"description": "",
|
||||
"type": "string"
|
||||
},
|
||||
"unwrap": {
|
||||
"description": "",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["name", "namespace", "version"]
|
||||
}
|
||||
29
package.json
Normal file
29
package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "browser-scripts-builder",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./lib/main.mjs",
|
||||
"module": "./lib/main.mjs",
|
||||
"bin": {
|
||||
"bsbuild": "./lib/main.js"
|
||||
},
|
||||
"scripts": {
|
||||
"prettier": "prettier --write .",
|
||||
"build": "npm run prettier && tsc",
|
||||
"test": "node ./test/test.mjs"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.zomo.dev/zomo/browser-scripts-builder"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.14.42"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.40",
|
||||
"eslint": "^8.17.0",
|
||||
"prettier": "^2.6.2"
|
||||
}
|
||||
}
|
||||
1083
pnpm-lock.yaml
generated
Normal file
1083
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
readme.md
Normal file
25
readme.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# browser-scripts-builder
|
||||
|
||||
builder for [browser-scripts](https://git.zomo.dev/zomo/browser-scripts)
|
||||
|
||||
## Source File Structure
|
||||
|
||||
```text
|
||||
Root
|
||||
├───<package.json/etc>
|
||||
└───scripts
|
||||
└───[each script folder]
|
||||
├───<tsconfig.json>
|
||||
├───<other files for main.ts>
|
||||
├───main.ts
|
||||
└───meta.json (optional)
|
||||
```
|
||||
|
||||
## Dist File Structure
|
||||
|
||||
```text
|
||||
Root
|
||||
├───<package.json/etc>
|
||||
└───dist
|
||||
└───[each script folder].user.js
|
||||
```
|
||||
64
src/main.ts
Normal file
64
src/main.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { build } from 'esbuild'
|
||||
import {
|
||||
lstatSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from 'fs'
|
||||
import { DistBase, DistPath, ScriptBase, ScriptPath } from './paths'
|
||||
import readMeta from './readmeta'
|
||||
|
||||
async function compileProject(name: string) {
|
||||
//read meta file
|
||||
let [metaJson, metaString] = readMeta(name)
|
||||
let outPath = DistPath(name)
|
||||
|
||||
await build({
|
||||
entryPoints: [ScriptPath(name).main],
|
||||
outfile: outPath,
|
||||
|
||||
target: 'esnext',
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
|
||||
bundle: true,
|
||||
minify: false,
|
||||
|
||||
define: {
|
||||
UserScriptName: `'${metaJson.name}'`,
|
||||
UserScriptNamespace: `'${metaJson.namespace}'`,
|
||||
UserScriptVersion: `'${metaJson.version}'`,
|
||||
|
||||
UserScriptDownloadURL: `'${metaJson.downloadURL}'`,
|
||||
UserScriptSupportURL: `'${metaJson.supportURL}'`,
|
||||
UserScriptHomepageURL: `'${metaJson.homepageURL}'`,
|
||||
},
|
||||
})
|
||||
|
||||
//add UserScript header
|
||||
let content = readFileSync(outPath).toString()
|
||||
|
||||
writeFileSync(outPath, metaString + content)
|
||||
}
|
||||
|
||||
if (!lstatSync('package.json').isFile()) {
|
||||
console.error('package.json not found, unwilling to run')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
//delete compiled scripts
|
||||
readdirSync(DistBase).forEach(file => unlinkSync(`${DistBase}/${file}`))
|
||||
|
||||
//compile scripts
|
||||
readdirSync(ScriptBase).forEach(name => {
|
||||
let path = ScriptPath(name)
|
||||
|
||||
if (
|
||||
!name.endsWith('_') &&
|
||||
lstatSync(path.dir).isDirectory() &&
|
||||
lstatSync(path.main).isFile()
|
||||
) {
|
||||
compileProject(name)
|
||||
}
|
||||
})
|
||||
16
src/paths.ts
Normal file
16
src/paths.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export const BaseUrl = `https://git.zomo.dev/zomo/browser-scripts`
|
||||
export const RemoteBranch = 'main'
|
||||
export const ScriptBase = 'scripts'
|
||||
export const DistBase = 'dist'
|
||||
|
||||
export const SupportUrl = `${BaseUrl}/issues`
|
||||
export const FileUrl = (name: string) =>
|
||||
`${BaseUrl}/raw/branch/${RemoteBranch}/${DistBase}/${name}.user.js`
|
||||
|
||||
export const ScriptPath = (name: string) => ({
|
||||
dir: `${ScriptBase}/${name}`,
|
||||
main: `${ScriptBase}/${name}/main.ts`,
|
||||
meta: `${ScriptBase}/${name}/meta.json`,
|
||||
})
|
||||
|
||||
export const DistPath = (name: string) => `${DistBase}/${name}.user.js`
|
||||
93
src/readmeta.ts
Normal file
93
src/readmeta.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { lstatSync, readFileSync } from 'fs'
|
||||
import { BaseUrl, FileUrl, ScriptPath, SupportUrl } from './paths'
|
||||
import { UserDataMeta, UserDataMetaFull, UserDataMetaPartial } from './types'
|
||||
|
||||
export default function (name: string): [UserDataMetaFull, string] {
|
||||
var meta: UserDataMetaFull = {
|
||||
name: name,
|
||||
namespace: 'zomo.dev',
|
||||
match: '',
|
||||
excludematch: '',
|
||||
version: '0.0.0',
|
||||
description: '',
|
||||
icon: '',
|
||||
require: '',
|
||||
resource: '',
|
||||
runat: '',
|
||||
noframes: false,
|
||||
grant: '',
|
||||
injectinto: '',
|
||||
downloadURL: FileUrl(name),
|
||||
supportURL: SupportUrl,
|
||||
homepageURL: BaseUrl,
|
||||
unwrap: false,
|
||||
}
|
||||
|
||||
let metaPath = ScriptPath(name).meta
|
||||
|
||||
if (lstatSync(metaPath).isFile()) {
|
||||
try {
|
||||
let args: UserDataMetaPartial = JSON.parse(
|
||||
readFileSync(metaPath).toString()
|
||||
)
|
||||
|
||||
let key: keyof UserDataMeta
|
||||
for (key in meta) {
|
||||
let val = args[key]
|
||||
|
||||
//cases where the value is empty
|
||||
if (val === undefined) continue
|
||||
if (val === false) continue
|
||||
if (val === '')
|
||||
continue
|
||||
|
||||
//:)
|
||||
;(meta[key] as any) = val
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
} else {
|
||||
console.log(`${metaPath} not found, using default metadata`)
|
||||
}
|
||||
|
||||
const keyConversion = {
|
||||
injectinto: 'inject-into',
|
||||
excludematch: 'exclude-match',
|
||||
}
|
||||
|
||||
return [
|
||||
meta,
|
||||
`// ==UserScript==
|
||||
${(Object.keys(meta) as Array<keyof UserDataMetaFull>)
|
||||
.filter(key => {
|
||||
let val = meta[key]
|
||||
if (val === undefined) return false
|
||||
if (val === false) return false
|
||||
if (val === '') return false
|
||||
return true
|
||||
})
|
||||
.map(key => {
|
||||
let val = meta[key]
|
||||
let key_str =
|
||||
key in keyConversion
|
||||
? keyConversion[key as keyof typeof keyConversion]
|
||||
: key
|
||||
key_str = key_str.padStart(12, ' ')
|
||||
|
||||
if (typeof val === 'boolean') {
|
||||
if (val) return `// @${key_str}`
|
||||
} else if (typeof val === 'string') {
|
||||
return `// @${key_str} ${val}`
|
||||
} else if (Array.isArray(val)) {
|
||||
return val.map(v => `// @${key_str} ${v}`).join('\n')
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
.filter(l => l.length)
|
||||
.join('\n')}
|
||||
// ==/UserScript==
|
||||
`,
|
||||
]
|
||||
}
|
||||
42
src/types.ts
Normal file
42
src/types.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
export interface UserDataMetaPartial {
|
||||
name?: string
|
||||
namespace?: string
|
||||
match?: string | string[]
|
||||
excludematch?: string | string[]
|
||||
version?: string
|
||||
description?: string
|
||||
icon?: string
|
||||
require?: string | string[]
|
||||
resource?: string | string[]
|
||||
runat?: 'document-start' | 'document-end' | 'document-idle' | ''
|
||||
noframes?: boolean
|
||||
grant?: string | string[]
|
||||
injectinto?: 'page' | 'content' | 'auto' | ''
|
||||
downloadURL?: string
|
||||
supportURL?: string
|
||||
homepageURL?: string
|
||||
unwrap?: boolean
|
||||
}
|
||||
|
||||
export interface UserDataMeta extends UserDataMetaPartial {
|
||||
name: string
|
||||
namespace: string
|
||||
version: string
|
||||
downloadURL: string
|
||||
supportURL: string
|
||||
homepageURL: string
|
||||
}
|
||||
|
||||
export interface UserDataMetaFull extends UserDataMeta {
|
||||
match: string | string[]
|
||||
excludematch: string | string[]
|
||||
description: string
|
||||
icon: string
|
||||
require: string | string[]
|
||||
resource: string | string[]
|
||||
runat: 'document-start' | 'document-end' | 'document-idle' | ''
|
||||
noframes: boolean
|
||||
grant: string | string[]
|
||||
injectinto: 'page' | 'content' | 'auto' | ''
|
||||
unwrap: boolean
|
||||
}
|
||||
0
test/test.mjs
Normal file
0
test/test.mjs
Normal file
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"module": "es2020",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"sourceMap": true,
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
}
|
||||
6
types/compiler_vars.d.ts
vendored
Normal file
6
types/compiler_vars.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
declare const UserScriptName: string
|
||||
declare const UserScriptNamespace: string
|
||||
declare const UserScriptVersion: string
|
||||
declare const UserScriptDownloadURL: string
|
||||
declare const UserScriptSupportURL: string
|
||||
declare const UserScriptHomepageURL: string
|
||||
Reference in New Issue
Block a user