create-tampermonkey-typescript 1.1.0 → 1.2.1

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.
package/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
- Copyright (c) 2026 neth392
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
-
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2026 neth392
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,62 +1,69 @@
1
- # create-tampermonkey-typescript
2
-
3
- > A CLI scaffolding tool for creating minimal TamperMonkey userscript projects written in TypeScript.
4
-
5
- Write your userscripts in TypeScript, organize code across multiple files, and let the toolchain handle the rest
6
- — bundling, CSS injection, and userscript header generation are all taken care of. The result is a single `.user.js`
7
- file ready to install in TamperMonkey.
8
-
9
- ---
10
-
11
- ## Features
12
-
13
- 📦 **TypeScript with multi-file support** — Structure your project however you like. All source files are bundled into
14
- a single IIFE-format JavaScript file via [Vite](https://vite.dev/), fully compatible with TamperMonkey.
15
-
16
- 🏷️ **Automatic userscript header** — The `// ==UserScript==` block is generated from a template (`userscript.txt`) and
17
- prepended to every build. Metadata fields such as name, version, and description are pulled directly from `package.json`,
18
- keeping a single source of truth.
19
-
20
- 🎨 **CSS injection** — Import `.css` files from TypeScript as you normally would. At build time, styles are extracted
21
- and bundled into the output script, then injected into the page at runtime — no manual DOM manipulation required.
22
-
23
- ⚛️ **Optional React support** — Scaffold the project with React pre-configured, including type declarations for
24
- `unsafeWindow.React` and `unsafeWindow.ReactDOM`, and utility functions for accessing them at runtime.
25
-
26
- 🚀 **GitHub Actions workflows** — Optionally include CI/CD workflows that automatically create Git tags when
27
- `package.json` version changes, and publish GitHub Releases with the built script attached.
28
-
29
- 🔧 **Package manager agnostic** Generated projects are standard Node.js projects. Use npm, yarn, or pnpm —
30
- whichever you prefer.
31
-
32
- ---
33
-
34
- ## Quick Start
35
-
36
- ### npm
37
-
38
- ```bash
39
- npx create-tampermonkey-typescript
40
- ```
41
-
42
- ### yarn
43
-
44
- ```bash
45
- yarn create tampermonkey-typescript
46
- ```
47
-
48
- ### pnpm
49
-
50
- ```bash
51
- pnpm create tampermonkey-typescript
52
- ```
53
-
54
- The CLI will walk you through the project configuration — name, version, description, author — and let you
55
- select optional features (React, Git). The output is your new project folder containing its own `README.md`
56
- to get you started. You can preview that file here: [Generated Project README](templates/base/README.md)
57
-
58
- ---
59
-
60
- ## License
61
-
1
+ # create-tampermonkey-typescript
2
+
3
+ > A CLI scaffolding tool for creating minimal TamperMonkey userscript projects written in TypeScript.
4
+
5
+ Write your userscripts in TypeScript, organize code across multiple files, and let the toolchain handle the rest
6
+ — bundling, CSS injection, and userscript header generation are all taken care of. The result is a single `.user.js`
7
+ file ready to install in TamperMonkey.
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ 📦 **TypeScript with multi-file support** — Structure your project however you like. All source files are bundled into
14
+ a single IIFE-format JavaScript file via [Vite](https://vite.dev/), fully compatible with TamperMonkey.
15
+
16
+ 🏷️ **Automatic userscript header** — The `// ==UserScript==` block is generated from a template (`userscript.txt`) and
17
+ prepended to every build. Metadata fields such as name, version, and description are pulled directly from `package.json`,
18
+ keeping a single source of truth.
19
+
20
+ 🔧 **Package manager agnostic** — Generated projects are standard Node.js projects. Use npm, yarn, or pnpm
21
+ whichever you prefer.
22
+
23
+ 🎨 **CSS injection** — Import `.css` files from TypeScript as you normally would. At build time, styles are extracted
24
+ and bundled into the output script, then injected into the page at runtime — no manual DOM manipulation required.
25
+
26
+ ### Optional Features
27
+
28
+ ⚛️ **React** — Scaffold the project with React pre-configured, including type declarations for
29
+ `unsafeWindow.React` and `unsafeWindow.ReactDOM`, and utility functions for accessing them at runtime.
30
+
31
+ 🌊 **Tailwind CSS** — Adds Tailwind CSS v4 with the Vite plugin, so utility classes are compiled
32
+ at build time and only the CSS you actually use is injected into your userscript.
33
+
34
+ **Prettier** — Sets up Prettier with a pre-configured `.prettierrc` and `.prettierignore` for consistent formatting.
35
+
36
+ 🚀 **GitHub Actions workflows** — Includes CI/CD workflows that automatically create Git tags when
37
+ `package.json` version changes, and publish GitHub Releases with the built script attached.
38
+
39
+ ---
40
+
41
+ ## Quick Start
42
+
43
+ ### npm
44
+
45
+ ```bash
46
+ npx create-tampermonkey-typescript
47
+ ```
48
+
49
+ ### yarn
50
+
51
+ ```bash
52
+ yarn create tampermonkey-typescript
53
+ ```
54
+
55
+ ### pnpm
56
+
57
+ ```bash
58
+ pnpm create tampermonkey-typescript
59
+ ```
60
+
61
+ The CLI will walk you through the project configuration — name, version, description, author — and let you
62
+ select optional features (React, Git). The output is your new project folder containing its own `README.md`
63
+ to get you started. You can preview that file here: [Generated Project README](templates/base/README.md)
64
+
65
+ ---
66
+
67
+ ## License
68
+
62
69
  [MIT](LICENSE)
package/dist/cli.js CHANGED
@@ -45,12 +45,27 @@ const availableFeatures = [
45
45
  tsConfigModifier: (config) => (config.compilerOptions.jsx = 'react-jsx'),
46
46
  devDependencies: ['react', 'react-dom', '@types/react', '@types/react-dom'],
47
47
  },
48
+ {
49
+ name: 'TailwindCSS',
50
+ description: 'Adds TailwindCSS support to the project',
51
+ directory: path.join(TEMPLATES_DIR, 'tailwindcss'),
52
+ devDependencies: ['tailwindcss', '@tailwindcss/vite'],
53
+ },
54
+ {
55
+ name: 'Prettier',
56
+ description: 'Adds Prettier with default .prettierrc and .prettierignore files',
57
+ directory: path.join(TEMPLATES_DIR, 'prettier'),
58
+ hook: (params) => {
59
+ renameDotFiles(params, 'prettierrc', 'prettierignore');
60
+ execInProjectDir('npm install --save-dev --save-exact prettier', params);
61
+ },
62
+ },
48
63
  {
49
64
  name: 'Git',
50
65
  description: 'Initializes the new project as a git repository',
51
66
  directory: path.join(TEMPLATES_DIR, 'git'),
52
67
  hook: (params) => {
53
- fs.renameSync(path.join(params.projectPath, '_gitignore'), path.join(params.projectPath, '.gitignore'));
68
+ renameDotFiles(params, 'gitignore');
54
69
  execInProjectDir(`git init && git add . && git commit -m "Initial commit"`, params);
55
70
  },
56
71
  },
@@ -282,4 +297,9 @@ function writeObjectToFile(object, fileName, params) {
282
297
  function execInProjectDir(command, params) {
283
298
  execSync(command, { stdio: 'inherit', cwd: params.projectPath });
284
299
  }
300
+ function renameDotFiles(params, ...fileNames) {
301
+ for (const fileName of fileNames) {
302
+ fs.renameSync(path.join(params.projectPath, `_${fileName}`), path.join(params.projectPath, `.${fileName}`));
303
+ }
304
+ }
285
305
  main().then(() => { }, (e) => console.error(kleur.red(e.message || e)));
package/package.json CHANGED
@@ -1,49 +1,51 @@
1
- {
2
- "name": "create-tampermonkey-typescript",
3
- "version": "1.1.0",
4
- "description": "CLI tool for generating a TamperMonkey script project written in typescript which is transpiled to JavaScript to be ran in the browser",
5
- "license": "MIT",
6
- "homepage": "https://github.com/neth392/create-tampermonkey-typescript",
7
- "author": "neth392",
8
- "keywords": [
9
- "tampermonkey",
10
- "typescript",
11
- "template"
12
- ],
13
- "publishConfig": {
14
- "access": "public",
15
- "registry": "https://registry.npmjs.org/"
16
- },
17
- "files": [
18
- "dist",
19
- "templates"
20
- ],
21
- "type": "module",
22
- "bin": {
23
- "create-tampermonkey-typescript": "dist/cli.js"
24
- },
25
- "scripts": {
26
- "build": "tsc",
27
- "dev": "ts-node src/cli.ts"
28
- },
29
- "devDependencies": {
30
- "@types/node": "^24.0.10",
31
- "@types/prompts": "^2.4.9",
32
- "@types/react": "^19.1.8",
33
- "@types/react-dom": "^19.1.6",
34
- "@types/tampermonkey": "^5.0.4",
35
- "prettier": "^3.6.1",
36
- "react": "^19.1.0",
37
- "react-dom": "^19.1.0",
38
- "ts-node": "^10.9.2",
39
- "type-fest": "^5.4.4",
40
- "typescript": "^5.8.3",
41
- "vite": "^7.0.0",
42
- "vite-plugin-banner": "^0.8.1",
43
- "vite-plugin-css-injected-by-js": "^3.5.2"
44
- },
45
- "dependencies": {
46
- "kleur": "^4.1.5",
47
- "prompts": "^2.4.2"
48
- }
49
- }
1
+ {
2
+ "name": "create-tampermonkey-typescript",
3
+ "version": "1.2.1",
4
+ "description": "CLI tool for generating a TamperMonkey script project written in typescript which is transpiled to JavaScript to be ran in the browser",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/neth392/create-tampermonkey-typescript",
7
+ "author": "neth392",
8
+ "keywords": [
9
+ "tampermonkey",
10
+ "typescript",
11
+ "template"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public",
15
+ "registry": "https://registry.npmjs.org/"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "templates"
20
+ ],
21
+ "type": "module",
22
+ "bin": {
23
+ "create-tampermonkey-typescript": "dist/cli.js"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "dev": "ts-node src/cli.ts"
28
+ },
29
+ "devDependencies": {
30
+ "@tailwindcss/vite": "^4.1.18",
31
+ "@types/node": "^24.0.10",
32
+ "@types/prompts": "^2.4.9",
33
+ "@types/react": "^19.1.8",
34
+ "@types/react-dom": "^19.1.6",
35
+ "@types/tampermonkey": "^5.0.4",
36
+ "prettier": "^3.6.1",
37
+ "react": "^19.1.0",
38
+ "react-dom": "^19.1.0",
39
+ "tailwindcss": "^4.1.18",
40
+ "ts-node": "^10.9.2",
41
+ "type-fest": "^5.4.4",
42
+ "typescript": "^5.8.3",
43
+ "vite": "^7.0.0",
44
+ "vite-plugin-banner": "^0.8.1",
45
+ "vite-plugin-css-injected-by-js": "^3.5.2"
46
+ },
47
+ "dependencies": {
48
+ "kleur": "^4.1.5",
49
+ "prompts": "^2.4.2"
50
+ }
51
+ }
@@ -11,6 +11,8 @@
11
11
  - 📚 [Dependencies](#dependencies)
12
12
  - 🐒 [TamperMonkey API](#tampermonkey-api)
13
13
  - ⚛️ [React](#react)
14
+ - 🌊 [TailwindCSS](#tailwind-css)
15
+ - ✨ [Prettier](#prettier)
14
16
  - ⚙️ [GitHub Workflows](#github-workflows)
15
17
 
16
18
 
@@ -182,6 +184,43 @@ root.render(<App />)
182
184
 
183
185
  ---
184
186
 
187
+ ## Tailwind CSS
188
+
189
+ Tailwind is configured via the `@tailwindcss/vite` plugin and imported in `src/styles.css`. Just use utility classes in your code — only the classes you reference will be included in the final build.
190
+ ```ts
191
+ const el = document.createElement('div')
192
+ el.className = 'bg-blue-500 text-white p-4 rounded'
193
+ document.body.appendChild(el)
194
+ ```
195
+
196
+ Or with React:
197
+ ```tsx
198
+ const Badge = ({ text, color }: { text: string; color: string }) => (
199
+ <span className={`inline-block px-3 py-1 rounded-full text-sm font-semibold text-white ${color}`}>
200
+ {text}
201
+ </span>
202
+ )
203
+
204
+ const App = () => (
205
+ <div className="flex gap-2 p-4">
206
+ <Badge text="Online" color="bg-green-500" />
207
+ <Badge text="Away" color="bg-yellow-500" />
208
+ <Badge text="Offline" color="bg-red-500" />
209
+ </div>
210
+ )
211
+
212
+ ```
213
+
214
+ For more information, see the [Tailwind CSS docs](https://tailwindcss.com/docs).
215
+
216
+ ---
217
+
218
+ ## Prettier
219
+
220
+ Prettier is included with a pre-configured `.prettierrc` and `.prettierignore` file. Feel free to change them to best fit your programming style.
221
+
222
+ ---
223
+
185
224
  ## GitHub Workflows
186
225
 
187
226
  > This section only applies if Git was enabled during project creation.
@@ -1,6 +1,6 @@
1
- /**
2
- This file is the entry point to your script.
3
- */
4
-
5
- // Imports your styles. Can be removed if no CSS is used.
6
- import '@/styles.css'
1
+ /**
2
+ This file is the entry point to your script.
3
+ */
4
+
5
+ // Imports your styles. Can be removed if no CSS is used.
6
+ import '@/styles.css'
@@ -1,7 +1,8 @@
1
- // ==UserScript==
2
- // @name <name>
3
- // @version <version>
4
- // @description <description>
5
- // @author <author>
6
- // @homepage <homepage>
1
+ // ==UserScript==
2
+ // @name <name>
3
+ // @version <version>
4
+ // @description <description>
5
+ // @author <author>
6
+ // @namespace <homepage>
7
+ // @homepage <homepage>
7
8
  // ==/UserScript==
@@ -1,55 +1,60 @@
1
- /**
2
- * Configured by create-tampermonkey-typescript to combine your entire codebase into a single TamperMonkey-ready script.
3
- * You can modify it as you like.
4
- */
5
-
6
- import { defineConfig } from 'vite'
7
- import { resolve, dirname } from 'path'
8
- import { fileURLToPath } from 'url'
9
- import fs from 'fs'
10
- import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
11
- import banner from 'vite-plugin-banner'
12
-
13
- const __filename = fileURLToPath(import.meta.url)
14
- const __dirname = dirname(__filename)
15
-
16
- const pkg = JSON.parse(fs.readFileSync(resolve(__dirname, 'package.json'), 'utf8'))
17
- const hasReact = pkg.devDependencies?.react || pkg.dependencies?.react
18
-
19
- // Replaced in the script's header to keep package.json as the source of truth.
20
- const metaTags = {
21
- '<name>': pkg.name,
22
- '<version>': pkg.version,
23
- '<description>': pkg.description,
24
- '<author>': pkg.author,
25
- '<homepage>': pkg.homepage,
26
- }
27
-
28
- let meta = fs.readFileSync(resolve(__dirname, 'userscript.txt'), 'utf8')
29
-
30
- for (const [tagName, tagValue] of Object.entries(metaTags).filter(([_, v]) => v)) {
31
- meta = meta.replace(tagName, tagValue)
32
- }
33
-
34
- export default defineConfig({
35
- resolve: {
36
- alias: {
37
- '@': resolve(__dirname, 'src'),
38
- },
39
- },
40
- plugins: [cssInjectedByJsPlugin({ topExecutionPriority: true }), banner({ content: meta, verify: false })],
41
- build: {
42
- cssCodeSplit: false,
43
- lib: {
44
- entry: resolve(__dirname, 'src/script.ts'),
45
- name: pkg.name.replace(/[^a-zA-Z0-9]/g, '_'),
46
- formats: ['iife'],
47
- fileName: () => `script.user.js`,
48
- },
49
- rollupOptions: {
50
- ...(hasReact ? { external: ['react', 'react-dom/client'] } : {}),
51
- },
52
- outDir: 'dist',
53
- minify: false,
54
- },
55
- })
1
+ /**
2
+ * Configured by create-tampermonkey-typescript to combine your entire codebase into a single TamperMonkey-ready script.
3
+ * You can modify it as you like.
4
+ */
5
+
6
+ import { defineConfig } from 'vite'
7
+ import { resolve, dirname } from 'path'
8
+ import { fileURLToPath } from 'url'
9
+ import fs from 'fs'
10
+ import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
11
+ import banner from 'vite-plugin-banner'
12
+
13
+ const __filename = fileURLToPath(import.meta.url)
14
+ const __dirname = dirname(__filename)
15
+
16
+ const pkg = JSON.parse(fs.readFileSync(resolve(__dirname, 'package.json'), 'utf8'))
17
+ const hasReact = pkg.devDependencies?.react || pkg.dependencies?.react
18
+ const hasTailwind = pkg.devDependencies?.['@tailwindcss/vite'] || pkg.dependencies?.['@tailwindcss/vite']
19
+
20
+ // Replaced in the script's header to keep package.json as the source of truth.
21
+ const metaTags = {
22
+ '<name>': pkg.name,
23
+ '<version>': pkg.version,
24
+ '<description>': pkg.description,
25
+ '<author>': pkg.author,
26
+ '<homepage>': pkg.homepage,
27
+ }
28
+
29
+ let meta = fs.readFileSync(resolve(__dirname, 'userscript.txt'), 'utf8')
30
+
31
+ for (const [tagName, tagValue] of Object.entries(metaTags).filter(([_, v]) => v)) {
32
+ meta = meta.replaceAll(tagName, tagValue)
33
+ }
34
+
35
+ export default defineConfig({
36
+ resolve: {
37
+ alias: {
38
+ '@': resolve(__dirname, 'src'),
39
+ },
40
+ },
41
+ plugins: [
42
+ ...(hasTailwind ? [(await import('@tailwindcss/vite')).default()] : []),
43
+ cssInjectedByJsPlugin({ topExecutionPriority: true }),
44
+ banner({ content: meta, verify: false }),
45
+ ],
46
+ build: {
47
+ cssCodeSplit: false,
48
+ lib: {
49
+ entry: resolve(__dirname, 'src/script.ts'),
50
+ name: pkg.name.replace(/[^a-zA-Z0-9]/g, '_'),
51
+ formats: ['iife'],
52
+ fileName: () => `script.user.js`,
53
+ },
54
+ rollupOptions: {
55
+ ...(hasReact ? { external: ['react', 'react-dom/client'] } : {}),
56
+ },
57
+ outDir: 'dist',
58
+ minify: false,
59
+ },
60
+ })
@@ -1,28 +1,28 @@
1
- # Project Specific
2
- dist/
3
-
4
- # Node
5
- node_modules/
6
- .vite/
7
-
8
- # Logs
9
- npm-debug.log*
10
- yarn-debug.log*
11
- yarn-error.log*
12
- pnpm-debug.log*
13
-
14
- # OS-specific
15
- .DS_Store
16
- Thumbs.db
17
-
18
- # VSCode
19
- .vscode/
20
-
21
- # Webstorm
22
- .idea
23
-
24
- # TypeScript
25
- *.tsbuildinfo
26
-
27
- # Prettier/Editor
1
+ # Project Specific
2
+ dist/
3
+
4
+ # Node
5
+ node_modules/
6
+ .vite/
7
+
8
+ # Logs
9
+ npm-debug.log*
10
+ yarn-debug.log*
11
+ yarn-error.log*
12
+ pnpm-debug.log*
13
+
14
+ # OS-specific
15
+ .DS_Store
16
+ Thumbs.db
17
+
18
+ # VSCode
19
+ .vscode/
20
+
21
+ # Webstorm
22
+ .idea
23
+
24
+ # TypeScript
25
+ *.tsbuildinfo
26
+
27
+ # Prettier/Editor
28
28
  .prettiercache/
@@ -1,42 +1,42 @@
1
- # .github/workflows/auto-tag.yml
2
- name: Auto Tag from package.json
3
-
4
- permissions:
5
- contents: write
6
-
7
- on:
8
- push:
9
- branches:
10
- - master
11
-
12
- jobs:
13
- tag:
14
- runs-on: ubuntu-latest
15
- steps:
16
- - name: Checkout code
17
- uses: actions/checkout@v4
18
- with:
19
- fetch-depth: 0 # Required to push tags
20
-
21
- - name: Setup Node
22
- uses: actions/setup-node@v4
23
- with:
24
- node-version: '20'
25
-
26
- - name: Read version from package.json
27
- id: pkg
28
- run: |
29
- VERSION=$(node -p "require('./package.json').version")
30
- echo "PACKAGE_VERSION=$VERSION" >> $GITHUB_ENV
31
- echo "TAG_NAME=v$VERSION" >> $GITHUB_ENV
32
-
33
- - name: Create tag if not exists
34
- run: |
35
- if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
36
- echo "Tag $TAG_NAME already exists. Skipping."
37
- else
38
- git config user.name "github-actions[bot]"
39
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
40
- git tag $TAG_NAME
41
- git push origin $TAG_NAME
1
+ # .github/workflows/auto-tag.yml
2
+ name: Auto Tag from package.json
3
+
4
+ permissions:
5
+ contents: write
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - master
11
+
12
+ jobs:
13
+ tag:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0 # Required to push tags
20
+
21
+ - name: Setup Node
22
+ uses: actions/setup-node@v4
23
+ with:
24
+ node-version: '20'
25
+
26
+ - name: Read version from package.json
27
+ id: pkg
28
+ run: |
29
+ VERSION=$(node -p "require('./package.json').version")
30
+ echo "PACKAGE_VERSION=$VERSION" >> $GITHUB_ENV
31
+ echo "TAG_NAME=v$VERSION" >> $GITHUB_ENV
32
+
33
+ - name: Create tag if not exists
34
+ run: |
35
+ if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
36
+ echo "Tag $TAG_NAME already exists. Skipping."
37
+ else
38
+ git config user.name "github-actions[bot]"
39
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
40
+ git tag $TAG_NAME
41
+ git push origin $TAG_NAME
42
42
  fi
@@ -1,56 +1,56 @@
1
- name: Build & Release Tampermonkey Script
2
-
3
- permissions:
4
- contents: write
5
-
6
- on:
7
- workflow_run:
8
- workflows: ["Auto Tag from package.json"]
9
- types:
10
- - completed
11
-
12
- jobs:
13
- release:
14
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
15
- runs-on: ubuntu-latest
16
-
17
- steps:
18
- - name: Checkout code
19
- uses: actions/checkout@v4
20
- with:
21
- fetch-depth: 0
22
- fetch-tags: true
23
-
24
- - name: Set up Node.js
25
- uses: actions/setup-node@v4
26
- with:
27
- check-latest: true
28
-
29
- - name: Install dependencies
30
- run: npm ci
31
-
32
- - name: Build script
33
- run: npm run build
34
-
35
- - name: Get package name
36
- id: pkg
37
- run: |
38
- NAME=$(node -p "require('./package.json').name")
39
- echo "PACKAGE_NAME=$NAME" >> $GITHUB_ENV
40
-
41
- - name: Get latest tag from Git
42
- id: tag
43
- run: |
44
- git fetch --tags
45
- TAG=$(git describe --tags --abbrev=0)
46
- echo "TAG_NAME=$TAG" >> $GITHUB_ENV
47
- echo "Latest tag: $TAG"
48
-
49
- - name: Create GitHub Release
50
- uses: softprops/action-gh-release@v2
51
- with:
52
- name: ${{ env.PACKAGE_NAME }} ${{ env.TAG_NAME }}
53
- tag_name: ${{ env.TAG_NAME }}
54
- files: dist/script.user.js
55
- env:
56
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1
+ name: Build & Release Tampermonkey Script
2
+
3
+ permissions:
4
+ contents: write
5
+
6
+ on:
7
+ workflow_run:
8
+ workflows: ["Auto Tag from package.json"]
9
+ types:
10
+ - completed
11
+
12
+ jobs:
13
+ release:
14
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+ fetch-tags: true
23
+
24
+ - name: Set up Node.js
25
+ uses: actions/setup-node@v4
26
+ with:
27
+ check-latest: true
28
+
29
+ - name: Install dependencies
30
+ run: npm ci
31
+
32
+ - name: Build script
33
+ run: npm run build
34
+
35
+ - name: Get package name
36
+ id: pkg
37
+ run: |
38
+ NAME=$(node -p "require('./package.json').name")
39
+ echo "PACKAGE_NAME=$NAME" >> $GITHUB_ENV
40
+
41
+ - name: Get latest tag from Git
42
+ id: tag
43
+ run: |
44
+ git fetch --tags
45
+ TAG=$(git describe --tags --abbrev=0)
46
+ echo "TAG_NAME=$TAG" >> $GITHUB_ENV
47
+ echo "Latest tag: $TAG"
48
+
49
+ - name: Create GitHub Release
50
+ uses: softprops/action-gh-release@v2
51
+ with:
52
+ name: ${{ env.PACKAGE_NAME }} ${{ env.TAG_NAME }}
53
+ tag_name: ${{ env.TAG_NAME }}
54
+ files: dist/script.user.js
55
+ env:
56
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,3 @@
1
+ dist/
2
+ node_modules/
3
+ *.user.js
@@ -0,0 +1,7 @@
1
+ {
2
+ "trailingComma": "es5",
3
+ "tabWidth": 2,
4
+ "semi": false,
5
+ "singleQuote": true,
6
+ "printWidth": 120
7
+ }
@@ -1,14 +1,14 @@
1
- /**
2
- * A reference to the global `window` object, extended with additional properties
3
- * for React and ReactDOM.
4
- *
5
- * @type {Window & {React: typeof import('react'), ReactDOM: typeof import('react-dom/client')}}
6
- * @property {typeof import('react')} React - The React library, providing tools
7
- * for building user interfaces.
8
- * @property {typeof import('react-dom/client')} ReactDOM - The ReactDOM library,
9
- * allowing React components to be rendered into the DOM.
10
- */
11
- declare const unsafeWindow: Window & {
12
- React: typeof import('react')
13
- ReactDOM: typeof import('react-dom/client')
14
- }
1
+ /**
2
+ * A reference to the global `window` object, extended with additional properties
3
+ * for React and ReactDOM.
4
+ *
5
+ * @type {Window & {React: typeof import('react'), ReactDOM: typeof import('react-dom/client')}}
6
+ * @property {typeof import('react')} React - The React library, providing tools
7
+ * for building user interfaces.
8
+ * @property {typeof import('react-dom/client')} ReactDOM - The ReactDOM library,
9
+ * allowing React components to be rendered into the DOM.
10
+ */
11
+ declare const unsafeWindow: Window & {
12
+ React: typeof import('react')
13
+ ReactDOM: typeof import('react-dom/client')
14
+ }
@@ -1,24 +1,24 @@
1
- /**
2
- * Optional utility file for easily accessing the React & ReactDOM objects at runtime.
3
- */
4
-
5
- import type React from 'react'
6
- import type ReactDOM from 'react-dom/client'
7
-
8
- /**
9
- * Retrieves the React object from the global `unsafeWindow` scope.
10
- *
11
- * @return {typeof React} The React object from the global scope.
12
- */
13
- export function getReact(): typeof React {
14
- return unsafeWindow.React
15
- }
16
-
17
- /**
18
- * Retrieves the ReactDOM object from the global `unsafeWindow` object.
19
- *
20
- * @return {typeof ReactDOM} The ReactDOM reference from the global scope.
21
- */
22
- export function getReactDOM(): typeof ReactDOM {
23
- return unsafeWindow.ReactDOM
24
- }
1
+ /**
2
+ * Optional utility file for easily accessing the React & ReactDOM objects at runtime.
3
+ */
4
+
5
+ import type React from 'react'
6
+ import type ReactDOM from 'react-dom/client'
7
+
8
+ /**
9
+ * Retrieves the React object from the global `unsafeWindow` scope.
10
+ *
11
+ * @return {typeof React} The React object from the global scope.
12
+ */
13
+ export function getReact(): typeof React {
14
+ return unsafeWindow.React
15
+ }
16
+
17
+ /**
18
+ * Retrieves the ReactDOM object from the global `unsafeWindow` object.
19
+ *
20
+ * @return {typeof ReactDOM} The ReactDOM reference from the global scope.
21
+ */
22
+ export function getReactDOM(): typeof ReactDOM {
23
+ return unsafeWindow.ReactDOM
24
+ }
@@ -0,0 +1,2 @@
1
+ /* Add all styles here, keep tailwindcss import for using tailwind */
2
+ @import 'tailwindcss';
@@ -1,16 +1,16 @@
1
- {
2
- "compilerOptions": {
3
- "jsx": "react-jsx",
4
- "types": ["vite/client", "node"],
5
- "target": "ES2022",
6
- "module": "ESNext",
7
- "moduleResolution": "nodenext",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "skipLibCheck": true,
12
- "resolveJsonModule": true,
13
- "lib": ["ES2022", "dom", "dom.iterable"]
14
- },
15
- "include": ["template/src", "react"]
16
- }
1
+ {
2
+ "compilerOptions": {
3
+ "jsx": "react-jsx",
4
+ "types": ["vite/client", "node"],
5
+ "target": "ES2022",
6
+ "module": "ESNext",
7
+ "moduleResolution": "nodenext",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "skipLibCheck": true,
12
+ "resolveJsonModule": true,
13
+ "lib": ["ES2022", "dom", "dom.iterable"]
14
+ },
15
+ "include": ["template/src", "react"]
16
+ }