Standardize screen position naming to snake_case
All checks were successful
Lint and Build / build (pull_request) Successful in 2m46s
All checks were successful
Lint and Build / build (pull_request) Successful in 2m46s
- Update screen position naming from camelCase to snake_case (top_left, top_right, bottom_left, bottom_right) - Refactor getActive route to use SCREEN_POSITIONS constant for DRY code - Update documentation to reflect new file naming convention - Remove unnecessary console.log for internal network requests in middleware - Improve code maintainability and consistency across the codebase 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2bb0c64326
commit
a89fa7c8d6
7 changed files with 4393 additions and 1607 deletions
|
@ -1,6 +1,7 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { createSuccessResponse, createErrorResponse, withErrorHandling } from '../../../lib/apiHelpers';
|
import { createSuccessResponse, createErrorResponse, withErrorHandling } from '../../../lib/apiHelpers';
|
||||||
|
import { SCREEN_POSITIONS } from '../../../lib/constants';
|
||||||
|
|
||||||
const FILE_DIRECTORY = path.resolve(process.env.FILE_DIRECTORY || './files')
|
const FILE_DIRECTORY = path.resolve(process.env.FILE_DIRECTORY || './files')
|
||||||
// Ensure directory exists
|
// Ensure directory exists
|
||||||
|
@ -11,31 +12,17 @@ console.log('using', FILE_DIRECTORY)
|
||||||
|
|
||||||
async function getActiveHandler() {
|
async function getActiveHandler() {
|
||||||
try {
|
try {
|
||||||
const largePath = path.join(FILE_DIRECTORY, 'large.txt');
|
const activeSources: Record<string, string | null> = {};
|
||||||
const leftPath = path.join(FILE_DIRECTORY, 'left.txt');
|
|
||||||
const rightPath = path.join(FILE_DIRECTORY, 'right.txt');
|
|
||||||
const topLeftPath = path.join(FILE_DIRECTORY, 'topLeft.txt');
|
|
||||||
const topRightPath = path.join(FILE_DIRECTORY, 'topRight.txt');
|
|
||||||
const bottomLeftPath = path.join(FILE_DIRECTORY, 'bottomLeft.txt');
|
|
||||||
const bottomRightPath = path.join(FILE_DIRECTORY, 'bottomRight.txt');
|
|
||||||
|
|
||||||
const large = fs.existsSync(largePath) ? fs.readFileSync(largePath, 'utf-8').trim() : null;
|
// Read each screen position file using the constant
|
||||||
const left = fs.existsSync(leftPath) ? fs.readFileSync(leftPath, 'utf-8').trim() : null;
|
for (const screen of SCREEN_POSITIONS) {
|
||||||
const right = fs.existsSync(rightPath) ? fs.readFileSync(rightPath, 'utf-8').trim() : null;
|
const filePath = path.join(FILE_DIRECTORY, `${screen}.txt`);
|
||||||
const topLeft = fs.existsSync(topLeftPath) ? fs.readFileSync(topLeftPath, 'utf-8').trim() : null;
|
activeSources[screen] = fs.existsSync(filePath)
|
||||||
const topRight = fs.existsSync(topRightPath) ? fs.readFileSync(topRightPath, 'utf-8').trim() : null;
|
? fs.readFileSync(filePath, 'utf-8').trim()
|
||||||
const bottomLeft = fs.existsSync(bottomLeftPath) ? fs.readFileSync(bottomLeftPath, 'utf-8').trim() : null;
|
: null;
|
||||||
const bottomRight = fs.existsSync(bottomRightPath) ? fs.readFileSync(bottomRightPath, 'utf-8').trim() : null;
|
}
|
||||||
|
|
||||||
return createSuccessResponse({
|
return createSuccessResponse(activeSources);
|
||||||
large,
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
topLeft,
|
|
||||||
topRight,
|
|
||||||
bottomLeft,
|
|
||||||
bottomRight
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error reading active sources:', error);
|
console.error('Error reading active sources:', error);
|
||||||
return createErrorResponse('Failed to read active sources', 500, 'Could not read source files', error);
|
return createErrorResponse('Failed to read active sources', 500, 'Could not read source files', error);
|
||||||
|
|
|
@ -17,10 +17,10 @@ You must create **exactly 7 Source Switcher sources** in OBS with these specific
|
||||||
| `ss_large` | Main/Large screen | `large.txt` |
|
| `ss_large` | Main/Large screen | `large.txt` |
|
||||||
| `ss_left` | Left screen | `left.txt` |
|
| `ss_left` | Left screen | `left.txt` |
|
||||||
| `ss_right` | Right screen | `right.txt` |
|
| `ss_right` | Right screen | `right.txt` |
|
||||||
| `ss_top_left` | Top left corner | `topLeft.txt` |
|
| `ss_top_left` | Top left corner | `top_left.txt` |
|
||||||
| `ss_top_right` | Top right corner | `topRight.txt` |
|
| `ss_top_right` | Top right corner | `top_right.txt` |
|
||||||
| `ss_bottom_left` | Bottom left corner | `bottomLeft.txt` |
|
| `ss_bottom_left` | Bottom left corner | `bottom_left.txt` |
|
||||||
| `ss_bottom_right` | Bottom right corner | `bottomRight.txt` |
|
| `ss_bottom_right` | Bottom right corner | `bottom_right.txt` |
|
||||||
|
|
||||||
## Setup Instructions
|
## Setup Instructions
|
||||||
|
|
||||||
|
|
3065
files/SaT.json.bak
3065
files/SaT.json.bak
File diff suppressed because it is too large
Load diff
|
@ -45,10 +45,10 @@ export const SCREEN_POSITIONS = [
|
||||||
'large',
|
'large',
|
||||||
'left',
|
'left',
|
||||||
'right',
|
'right',
|
||||||
'topLeft',
|
'top_left',
|
||||||
'topRight',
|
'top_right',
|
||||||
'bottomLeft',
|
'bottom_left',
|
||||||
'bottomRight'
|
'bottom_right'
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export const SOURCE_SWITCHER_NAMES = [
|
export const SOURCE_SWITCHER_NAMES = [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Security utilities for input validation and sanitization
|
// Security utilities for input validation and sanitization
|
||||||
|
|
||||||
export const VALID_SCREENS = ['large', 'left', 'right', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'] as const;
|
export const VALID_SCREENS = ['large', 'left', 'right', 'top_left', 'top_right', 'bottom_left', 'bottom_right'] as const;
|
||||||
export type ValidScreen = typeof VALID_SCREENS[number];
|
export type ValidScreen = typeof VALID_SCREENS[number];
|
||||||
|
|
||||||
// Input validation functions
|
// Input validation functions
|
||||||
|
|
|
@ -21,10 +21,6 @@ export function middleware(request: NextRequest) {
|
||||||
// Skip authentication for localhost/internal requests (optional security)
|
// Skip authentication for localhost/internal requests (optional security)
|
||||||
const host = request.headers.get('host');
|
const host = request.headers.get('host');
|
||||||
if (host && (host.startsWith('localhost') || host.startsWith('127.0.0.1') || host.startsWith('192.168.'))) {
|
if (host && (host.startsWith('localhost') || host.startsWith('127.0.0.1') || host.startsWith('192.168.'))) {
|
||||||
// Don't log for frequently polled endpoints to reduce noise
|
|
||||||
if (!request.nextUrl.pathname.includes('/api/obsStatus')) {
|
|
||||||
console.log('Allowing internal network access without API key');
|
|
||||||
}
|
|
||||||
return NextResponse.next();
|
return NextResponse.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2878
package-lock.json
generated
2878
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue