This commit is contained in:
2022-06-06 21:00:10 -05:00
commit 1e94d1a8ed
23 changed files with 1693 additions and 0 deletions

50
.eslintrc.json Normal file
View 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
View File

@@ -0,0 +1 @@
node_modules

1
.prettierignore Normal file
View File

@@ -0,0 +1 @@
dist/*

10
.prettierrc Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=types.js.map

1
lib/types.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}

103
meta.schema.json Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

25
readme.md Normal file
View 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
View 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
View 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
View 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
View 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
View File

17
tsconfig.json Normal file
View 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
View 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