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 fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
|
import syncVersion from "./syncVersion.js";
|
||||||
|
|
||||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
||||||
const frontendDir = path.join(__dirname, "frontend");
|
const frontendDir = path.join(__dirname, "frontend");
|
||||||
@ -10,21 +11,23 @@ const srcDir = path.join(__dirname, "src");
|
|||||||
const iconDir = path.join(__dirname, "icons");
|
const iconDir = path.join(__dirname, "icons");
|
||||||
const releaseDir = path.join(__dirname, "extension-release");
|
const releaseDir = path.join(__dirname, "extension-release");
|
||||||
|
|
||||||
function run(cmd, cwd) {
|
const run = (cmd, cwd) => {
|
||||||
console.log(`🛠️ Running: ${cmd}`);
|
console.log(`🛠️ Running: ${cmd}`);
|
||||||
execSync(cmd, { cwd, stdio: "inherit" });
|
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.mkdir(dest, { recursive: true });
|
||||||
await fs.promises.cp(src, dest, {
|
await fs.promises.cp(src, dest, {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
force: true,
|
force: true,
|
||||||
filter: (src) => !src.endsWith(".map"),
|
filter: (src) => !src.endsWith(".map"),
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
await syncVersion();
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log("🚀 Starting extension build...");
|
console.log("🚀 Starting extension build...");
|
||||||
|
|
||||||
// 1. Install frontend deps if needed
|
// 1. Install frontend deps if needed
|
||||||
@ -57,7 +60,7 @@ async function main() {
|
|||||||
await copyDir(iconDir, path.join(releaseDir, "icons"));
|
await copyDir(iconDir, path.join(releaseDir, "icons"));
|
||||||
|
|
||||||
console.log("✅ Build complete! extension-release ready.");
|
console.log("✅ Build complete! extension-release ready.");
|
||||||
}
|
};
|
||||||
|
|
||||||
main().catch((e) => {
|
main().catch((e) => {
|
||||||
console.error("❌ Build failed:", e);
|
console.error("❌ Build failed:", e);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>CDRM Decryption Extension</title>
|
<title>CDRM Decryption Extension v%APPVERSION%</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="min-w-full min-h-full w-full h-full">
|
<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>
|
<div class="min-w-full min-h-full w-full h-full" id="root"></div>
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "2.1.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-router-dom": "^7.7.0",
|
"react-router-dom": "^7.7.0",
|
||||||
"tailwindcss": "^4.1.11"
|
"tailwindcss": "^4.1.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.31.0",
|
"@eslint/js": "^9.31.0",
|
||||||
"@types/react": "^19.1.8",
|
"@types/react": "^19.1.8",
|
||||||
"@types/react-dom": "^19.1.6",
|
"@types/react-dom": "^19.1.6",
|
||||||
"@vitejs/plugin-react": "^4.7.0",
|
"@vitejs/plugin-react": "^4.7.0",
|
||||||
"eslint": "^9.31.0",
|
"eslint": "^9.31.0",
|
||||||
"eslint-plugin-react-hooks": "^5.2.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.20",
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.3.0",
|
||||||
"vite": "^7.0.5"
|
"vite": "^7.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,21 @@
|
|||||||
import { defineConfig } from "vite";
|
|
||||||
import react from "@vitejs/plugin-react";
|
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
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/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: "./",
|
base: "./",
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss(), replaceVersionPlugin()],
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cdrm-extension",
|
"name": "cdrm-extension",
|
||||||
"version": "1.0.0",
|
"version": "2.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "background.js",
|
"main": "background.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,41 +1,49 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "CDRM Extension 2.0",
|
"name": "CDRM Extension",
|
||||||
"version": "2.0",
|
"version": "2.1.0",
|
||||||
"description": "Decrypt DRM Protected content",
|
"description": "Decrypt DRM protected content",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"webRequest",
|
"webRequest",
|
||||||
"webRequestBlocking",
|
"webRequestBlocking",
|
||||||
"<all_urls>",
|
"<all_urls>",
|
||||||
"activeTab",
|
"activeTab",
|
||||||
"storage",
|
"storage",
|
||||||
"tabs",
|
"tabs",
|
||||||
"contextMenus"
|
"contextMenus"
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"scripts": [
|
||||||
|
"background.js"
|
||||||
],
|
],
|
||||||
"background": {
|
"persistent": true
|
||||||
"scripts": ["background.js"],
|
},
|
||||||
"persistent": true
|
"content_scripts": [
|
||||||
},
|
{
|
||||||
"content_scripts": [
|
"matches": [
|
||||||
{
|
"<all_urls>"
|
||||||
"matches": ["<all_urls>"],
|
],
|
||||||
"js": ["content.js"],
|
"js": [
|
||||||
"run_at": "document_start",
|
"content.js"
|
||||||
"all_frames": true
|
],
|
||||||
}
|
"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"
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"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