forked from tpd94/CDRM-Extension
dynamically add version to extension title bar and manifest.json, add readme
This commit is contained in:
parent
53aa7d66e3
commit
9c738d8a3e
49
README.md
Normal file
49
README.md
Normal file
@ -0,0 +1,49 @@
|
||||
# CDRM Extension
|
||||
|
||||
An extension to show keys from DRM protected content, which are used to decrypt content.
|
||||
|
||||
## Notes
|
||||
|
||||
Keep these extension core files inside `src`:
|
||||
|
||||
- `background.js`
|
||||
- `content.js`
|
||||
- `inject.js`
|
||||
- `manifest.json`
|
||||
|
||||
Frontend React source stays in `frontend`.
|
||||
|
||||
The build process will take care of everything into `extension-release`.
|
||||
|
||||
To update the version across the entire project, simply change the version number in the root `package.json`. The build script will handle version sync automatically to both the extension's version and the frontend's title bar.
|
||||
|
||||
## Build instructions
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js v21 or higher. [Download Node.js here](https://nodejs.org/en/download).
|
||||
|
||||
### How to build by yourself
|
||||
|
||||
- Open terminal at the project root
|
||||
|
||||
- Run the build script:
|
||||
|
||||
```bash
|
||||
npm run buildext
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- Sync the version number from the root `package.json` to `src/manifest.json` and `frontend/package.json`
|
||||
- Install frontend dependencies if needed
|
||||
- Build the React frontend
|
||||
- Clean and prepare the `extension-release` folder
|
||||
- Copy extension files in `src`, built frontend assets, and icons into `extension-release`
|
||||
|
||||
### How to load the extension in Google Chrome or Chromium browsers
|
||||
|
||||
1. Go to `chrome://extensions/`
|
||||
2. Enable **Developer mode**
|
||||
3. Click **Load unpacked** and select the `extension-release` folder
|
||||
4. Verify the extension is working by clicking its icon or opening the developer console (F12) to check for any logs or errors.
|
15
buildext.js
15
buildext.js
@ -2,6 +2,7 @@ import { execSync } from "child_process";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
import syncVersion from "./syncVersion.js";
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
||||
const frontendDir = path.join(__dirname, "frontend");
|
||||
@ -10,21 +11,23 @@ const srcDir = path.join(__dirname, "src");
|
||||
const iconDir = path.join(__dirname, "icons");
|
||||
const releaseDir = path.join(__dirname, "extension-release");
|
||||
|
||||
function run(cmd, cwd) {
|
||||
const run = (cmd, cwd) => {
|
||||
console.log(`🛠️ Running: ${cmd}`);
|
||||
execSync(cmd, { cwd, stdio: "inherit" });
|
||||
}
|
||||
};
|
||||
|
||||
async function copyDir(src, dest) {
|
||||
const copyDir = async (src, dest) => {
|
||||
await fs.promises.mkdir(dest, { recursive: true });
|
||||
await fs.promises.cp(src, dest, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
filter: (src) => !src.endsWith(".map"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
await syncVersion();
|
||||
|
||||
async function main() {
|
||||
console.log("🚀 Starting extension build...");
|
||||
|
||||
// 1. Install frontend deps if needed
|
||||
@ -57,7 +60,7 @@ async function main() {
|
||||
await copyDir(iconDir, path.join(releaseDir, "icons"));
|
||||
|
||||
console.log("✅ Build complete! extension-release ready.");
|
||||
}
|
||||
};
|
||||
|
||||
main().catch((e) => {
|
||||
console.error("❌ Build failed:", e);
|
||||
|
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>CDRM Decryption Extension</title>
|
||||
<title>CDRM Decryption Extension v%APPVERSION%</title>
|
||||
</head>
|
||||
<body class="min-w-full min-h-full w-full h-full">
|
||||
<div class="min-w-full min-h-full w-full h-full" id="root"></div>
|
||||
|
@ -1,30 +1,30 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-router-dom": "^7.7.0",
|
||||
"tailwindcss": "^4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.7.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.3.0",
|
||||
"vite": "^7.0.5"
|
||||
}
|
||||
}
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "2.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-router-dom": "^7.7.0",
|
||||
"tailwindcss": "^4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.7.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.3.0",
|
||||
"vite": "^7.0.5"
|
||||
}
|
||||
}
|
@ -1,9 +1,21 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { readFileSync } from "fs";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
const packageJson = JSON.parse(readFileSync("./package.json", "utf8"));
|
||||
|
||||
const replaceVersionPlugin = () => {
|
||||
return {
|
||||
name: "replace-version",
|
||||
transformIndexHtml(html) {
|
||||
return html.replace("%APPVERSION%", packageJson.version);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
base: "./",
|
||||
plugins: [react(), tailwindcss()],
|
||||
plugins: [react(), tailwindcss(), replaceVersionPlugin()],
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cdrm-extension",
|
||||
"version": "1.0.0",
|
||||
"version": "2.1.0",
|
||||
"description": "",
|
||||
"main": "background.js",
|
||||
"scripts": {
|
||||
|
@ -1,41 +1,49 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "CDRM Extension 2.0",
|
||||
"version": "2.0",
|
||||
"description": "Decrypt DRM Protected content",
|
||||
"permissions": [
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"<all_urls>",
|
||||
"activeTab",
|
||||
"storage",
|
||||
"tabs",
|
||||
"contextMenus"
|
||||
"manifest_version": 2,
|
||||
"name": "CDRM Extension",
|
||||
"version": "2.1.0",
|
||||
"description": "Decrypt DRM protected content",
|
||||
"permissions": [
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"<all_urls>",
|
||||
"activeTab",
|
||||
"storage",
|
||||
"tabs",
|
||||
"contextMenus"
|
||||
],
|
||||
"background": {
|
||||
"scripts": [
|
||||
"background.js"
|
||||
],
|
||||
"background": {
|
||||
"scripts": ["background.js"],
|
||||
"persistent": true
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["content.js"],
|
||||
"run_at": "document_start",
|
||||
"all_frames": true
|
||||
}
|
||||
],
|
||||
"web_accessible_resources": ["inject.js"],
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"16": "icons/icon16.png",
|
||||
"32": "icons/icon32.png",
|
||||
"128": "icons/icon128.png"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/icon16.png",
|
||||
"32": "icons/icon32.png",
|
||||
"128": "icons/icon128.png"
|
||||
"persistent": true
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"js": [
|
||||
"content.js"
|
||||
],
|
||||
"run_at": "document_start",
|
||||
"all_frames": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
"inject.js"
|
||||
],
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"browser_action": {
|
||||
"default_icon": {
|
||||
"16": "icons/icon16.png",
|
||||
"32": "icons/icon32.png",
|
||||
"128": "icons/icon128.png"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/icon16.png",
|
||||
"32": "icons/icon32.png",
|
||||
"128": "icons/icon128.png"
|
||||
}
|
||||
}
|
46
syncVersion.js
Normal file
46
syncVersion.js
Normal file
@ -0,0 +1,46 @@
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const syncVersion = async () => {
|
||||
const rootPkgPath = path.join(__dirname, "package.json");
|
||||
const frontendPkgPath = path.join(__dirname, "frontend", "package.json");
|
||||
const manifestPath = path.join(__dirname, "src", "manifest.json");
|
||||
|
||||
// Read root package.json version
|
||||
const rootPkgRaw = await fs.readFile(rootPkgPath, "utf-8");
|
||||
const rootPkg = JSON.parse(rootPkgRaw);
|
||||
const version = rootPkg.version;
|
||||
|
||||
if (!version) {
|
||||
console.warn("⚠️ No version field found in root package.json, skipping sync.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update frontend/package.json if exists
|
||||
try {
|
||||
const frontendPkgRaw = await fs.readFile(frontendPkgPath, "utf-8");
|
||||
const frontendPkg = JSON.parse(frontendPkgRaw);
|
||||
frontendPkg.version = version;
|
||||
await fs.writeFile(frontendPkgPath, JSON.stringify(frontendPkg, null, 2));
|
||||
console.log(`🔄 Updated frontend/package.json version to ${version}`);
|
||||
} catch {
|
||||
console.log("ℹ️ frontend/package.json not found or unreadable, skipping version update.");
|
||||
}
|
||||
|
||||
// Update src/manifest.json version
|
||||
try {
|
||||
const manifestRaw = await fs.readFile(manifestPath, "utf-8");
|
||||
const manifest = JSON.parse(manifestRaw);
|
||||
manifest.version = version;
|
||||
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
||||
console.log(`🔄 Updated src/manifest.json version to ${version}`);
|
||||
} catch (err) {
|
||||
console.error(`❌ Failed to update src/manifest.json version: ${err.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
export default syncVersion;
|
Loading…
x
Reference in New Issue
Block a user