diff --git a/resources/scripts/scaffold-discord-oauth-vue3-vite.mjs b/resources/scripts/scaffold-discord-oauth-vue3-vite.mjs index 21deefe..b9390a1 100755 --- a/resources/scripts/scaffold-discord-oauth-vue3-vite.mjs +++ b/resources/scripts/scaffold-discord-oauth-vue3-vite.mjs @@ -1,17 +1,17 @@ #!/usr/bin/env node -import fs from 'node:fs'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; const TEMPLATE_ROOT = path.resolve( path.dirname(fileURLToPath(import.meta.url)), - '..', - 'templates', - 'discord-oauth-vue3-vite', - 'src', - 'server', - 'discord-oauth', + "..", + "templates", + "discord-oauth-vue3-vite", + "src", + "server", + "discord-oauth", ); function usage() { @@ -32,52 +32,52 @@ Optional: function parseArgs(argv) { const options = { - mode: 'dry-run', - frontendOrigin: 'http://localhost:5173', - allowlistDiscordIds: '', - scopes: 'identify,email', + mode: "dry-run", + frontendOrigin: "http://localhost:5173", + allowlistDiscordIds: "", + scopes: "identify,email", force: false, }; for (let index = 0; index < argv.length; index += 1) { const arg = argv[index]; - if (arg === '--help') { + if (arg === "--help") { usage(); process.exit(0); } - if (arg === '--project-root') { + if (arg === "--project-root") { options.projectRoot = argv[index + 1]; index += 1; continue; } - if (arg === '--mode') { + if (arg === "--mode") { options.mode = argv[index + 1]; index += 1; continue; } - if (arg === '--frontend-origin') { + if (arg === "--frontend-origin") { options.frontendOrigin = argv[index + 1]; index += 1; continue; } - if (arg === '--allowlist-discord-ids') { + if (arg === "--allowlist-discord-ids") { options.allowlistDiscordIds = argv[index + 1]; index += 1; continue; } - if (arg === '--scopes') { + if (arg === "--scopes") { options.scopes = argv[index + 1]; index += 1; continue; } - if (arg === '--force') { + if (arg === "--force") { options.force = true; continue; } @@ -86,24 +86,29 @@ function parseArgs(argv) { } if (!options.projectRoot) { - throw new Error('--project-root is required.'); + throw new Error("--project-root is required."); } - if (!['dry-run', 'apply'].includes(options.mode)) { - throw new Error('--mode must be dry-run or apply.'); + if (!["dry-run", "apply"].includes(options.mode)) { + throw new Error("--mode must be dry-run or apply."); } options.projectRoot = path.resolve(options.projectRoot); - options.targetRoot = path.join(options.projectRoot, 'src', 'server', 'discord-oauth'); + options.targetRoot = path.join( + options.projectRoot, + "src", + "server", + "discord-oauth", + ); options.allowlistDiscordIdsJson = JSON.stringify( options.allowlistDiscordIds - .split(',') + .split(",") .map((entry) => entry.trim()) .filter(Boolean), ); options.scopesJson = JSON.stringify( options.scopes - .split(',') + .split(",") .map((entry) => entry.trim()) .filter(Boolean), ); @@ -111,7 +116,7 @@ function parseArgs(argv) { } function ensureDir(dirPath, mode) { - if (mode === 'dry-run') { + if (mode === "dry-run") { return; } fs.mkdirSync(dirPath, { recursive: true }); @@ -123,9 +128,12 @@ function isTextFile(filePath) { function replacePlaceholders(content, options) { return content - .replaceAll('__FRONTEND_ORIGIN__', options.frontendOrigin) - .replaceAll('__ALLOWLIST_DISCORD_IDS_JSON__', options.allowlistDiscordIdsJson) - .replaceAll('__SCOPES_JSON__', options.scopesJson); + .replaceAll("__FRONTEND_ORIGIN__", options.frontendOrigin) + .replaceAll( + "__ALLOWLIST_DISCORD_IDS_JSON__", + options.allowlistDiscordIdsJson, + ) + .replaceAll("__SCOPES_JSON__", options.scopesJson); } function walkFiles(rootDir, callback) { @@ -154,16 +162,16 @@ function scaffold(options) { const exists = fs.existsSync(targetPath); if (exists && !options.force) { - results.push({ action: 'skipped', filePath: targetPath }); + results.push({ action: "skipped", filePath: targetPath }); return; } - const action = exists ? 'updated' : 'created'; - if (options.mode === 'apply') { + const action = exists ? "updated" : "created"; + if (options.mode === "apply") { ensureDir(path.dirname(targetPath), options.mode); const rawContent = fs.readFileSync(sourcePath); const content = isTextFile(sourcePath) - ? replacePlaceholders(rawContent.toString('utf8'), options) + ? replacePlaceholders(rawContent.toString("utf8"), options) : rawContent; fs.writeFileSync(targetPath, content); } @@ -177,17 +185,21 @@ function scaffold(options) { function main() { const options = parseArgs(process.argv.slice(2)); - console.log(`Target bundle: ${path.relative(options.projectRoot, options.targetRoot)}`); + console.log( + `Target bundle: ${path.relative(options.projectRoot, options.targetRoot)}`, + ); console.log(`Mode: ${options.mode}`); const results = scaffold(options); for (const result of results) { - console.log(`${result.action.toUpperCase()}: ${path.relative(options.projectRoot, result.filePath)}`); + console.log( + `${result.action.toUpperCase()}: ${path.relative(options.projectRoot, result.filePath)}`, + ); } - if (options.mode === 'dry-run') { - console.log('Dry-run only. Re-run with --mode apply to write files.'); + if (options.mode === "dry-run") { + console.log("Dry-run only. Re-run with --mode apply to write files."); } } -main(); \ No newline at end of file +main(); diff --git a/resources/scripts/update-port-registry.mjs b/resources/scripts/update-port-registry.mjs index 750deb3..e697ac3 100644 --- a/resources/scripts/update-port-registry.mjs +++ b/resources/scripts/update-port-registry.mjs @@ -131,7 +131,10 @@ function normalizePorts(rawPorts) { }); } - ports.sort((left, right) => left.port - right.port || left.service.localeCompare(right.service)); + ports.sort( + (left, right) => + left.port - right.port || left.service.localeCompare(right.service), + ); return ports; } @@ -256,7 +259,9 @@ function buildPortIndexes(projects) { for (const entries of Object.values(ports)) { entries.sort((left, right) => { - const leftSeen = left.firstSeenAt ? Date.parse(left.firstSeenAt) : Number.POSITIVE_INFINITY; + const leftSeen = left.firstSeenAt + ? Date.parse(left.firstSeenAt) + : Number.POSITIVE_INFINITY; const rightSeen = right.firstSeenAt ? Date.parse(right.firstSeenAt) : Number.POSITIVE_INFINITY; @@ -296,7 +301,12 @@ function buildPortIndexes(projects) { * localSnapshot: LocalSnapshot * }} params */ -function updateRegistry({ stateDir, projectContext, localSnapshotPath, localSnapshot }) { +function updateRegistry({ + stateDir, + projectContext, + localSnapshotPath, + localSnapshot, +}) { ensureDirectory(stateDir); const registryPath = path.join(stateDir, machineRegistryName); @@ -348,7 +358,11 @@ function updateRegistry({ stateDir, projectContext, localSnapshotPath, localSnap function appendError(stateDir, errorMessage) { ensureDirectory(stateDir); const errorLine = `${nowIso()} ${errorMessage}`; - fs.appendFileSync(path.join(stateDir, "project-ports-errors.log"), `${errorLine}\n`, "utf8"); + fs.appendFileSync( + path.join(stateDir, "project-ports-errors.log"), + `${errorLine}\n`, + "utf8", + ); } function readStdin() { @@ -405,9 +419,10 @@ function runReport(stateDir) { throw parseError; } - const conflicts = registry.conflicts && typeof registry.conflicts === "object" - ? registry.conflicts - : {}; + const conflicts = + registry.conflicts && typeof registry.conflicts === "object" + ? registry.conflicts + : {}; const summary = { registryPath, @@ -445,9 +460,13 @@ function main() { } } - const projectContext = detectProjectContext(eventPayload, options.projectPath); + const projectContext = detectProjectContext( + eventPayload, + options.projectPath, + ); - const { localSnapshotPath, localSnapshot } = loadAndSyncLocalSnapshot(projectContext); + const { localSnapshotPath, localSnapshot } = + loadAndSyncLocalSnapshot(projectContext); updateRegistry({ stateDir: options.stateDir, projectContext, @@ -459,6 +478,9 @@ function main() { try { main(); } catch (error) { - appendError(defaultStateDir, error instanceof Error ? error.message : String(error)); + appendError( + defaultStateDir, + error instanceof Error ? error.message : String(error), + ); process.exitCode = 1; } diff --git a/resources/scripts/update-port-registry.test.mjs b/resources/scripts/update-port-registry.test.mjs index 7b60201..84843cd 100644 --- a/resources/scripts/update-port-registry.test.mjs +++ b/resources/scripts/update-port-registry.test.mjs @@ -27,7 +27,9 @@ function readJson(filePath) { } test("creates local snapshot and machine registry", () => { - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-port-registry-")); + const tempDir = fs.mkdtempSync( + path.join(os.tmpdir(), "copilot-port-registry-"), + ); const stateDir = path.join(tempDir, "state"); const projectPath = path.join(tempDir, "workspace-a"); fs.mkdirSync(projectPath, { recursive: true }); @@ -40,7 +42,11 @@ test("creates local snapshot and machine registry", () => { assert.equal(result.status, 0, result.stderr); - const localSnapshotPath = path.join(projectPath, ".local", "project-ports.json"); + const localSnapshotPath = path.join( + projectPath, + ".local", + "project-ports.json", + ); assert.equal(fs.existsSync(localSnapshotPath), true); const localSnapshot = readJson(localSnapshotPath); @@ -53,7 +59,9 @@ test("creates local snapshot and machine registry", () => { }); test("reports conflict and recommends changing newest project", () => { - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-port-registry-")); + const tempDir = fs.mkdtempSync( + path.join(os.tmpdir(), "copilot-port-registry-"), + ); const stateDir = path.join(tempDir, "state"); const projectA = path.join(tempDir, "workspace-a"); @@ -118,7 +126,9 @@ test("reports conflict and recommends changing newest project", () => { }); test("keeps firstSeenAt stable across re-sync", () => { - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "copilot-port-registry-")); + const tempDir = fs.mkdtempSync( + path.join(os.tmpdir(), "copilot-port-registry-"), + ); const stateDir = path.join(tempDir, "state"); const projectPath = path.join(tempDir, "workspace-a"); fs.mkdirSync(path.join(projectPath, ".local"), { recursive: true });