feat: add APK filename parser utilities
- Add detectEnvironment() to parse environment from APK filenames - Add parseApkFilename() to extract environment and commit ID metadata - Support dev, sandbox, product, and other environment types - Map environment patterns: timeshift, lan, dev -> dev; sandbox -> sandbox - Detect product APKs when no environment suffix present - Handle invalid formats gracefully
This commit is contained in:
56
lib/__tests__/apk-parser.test.ts
Normal file
56
lib/__tests__/apk-parser.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { parseApkFilename, detectEnvironment } from '../apk-parser';
|
||||
|
||||
describe('parseApkFilename', () => {
|
||||
it('should parse APK with environment suffix', () => {
|
||||
const result = parseApkFilename('ft_timeshift_0_42_57ef3a60d.apk');
|
||||
expect(result.environment).toBe('dev');
|
||||
expect(result.commit).toBe('57ef3a60d');
|
||||
expect(result.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should parse APK without environment (product)', () => {
|
||||
const result = parseApkFilename('ft_0_42_ff9ff3441.apk');
|
||||
expect(result.environment).toBe('product');
|
||||
expect(result.commit).toBe('ff9ff3441');
|
||||
expect(result.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should parse sandbox APK', () => {
|
||||
const result = parseApkFilename('ft_sandbox_0_42_57ef3a60d.apk');
|
||||
expect(result.environment).toBe('sandbox');
|
||||
expect(result.commit).toBe('57ef3a60d');
|
||||
expect(result.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle invalid format', () => {
|
||||
const result = parseApkFilename('invalid_filename.apk');
|
||||
expect(result.environment).toBe('other');
|
||||
expect(result.commit).toBeNull();
|
||||
expect(result.isValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle missing commit ID', () => {
|
||||
const result = parseApkFilename('ft_dev_0_42.apk');
|
||||
expect(result.environment).toBe('dev');
|
||||
expect(result.commit).toBeNull();
|
||||
expect(result.isValid).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectEnvironment', () => {
|
||||
it('should detect dev environment', () => {
|
||||
expect(detectEnvironment('ft_timeshift_0_42_57ef3a60d.apk')).toBe('dev');
|
||||
});
|
||||
|
||||
it('should detect sandbox environment', () => {
|
||||
expect(detectEnvironment('ft_sandbox_0_42_57ef3a60d.apk')).toBe('sandbox');
|
||||
});
|
||||
|
||||
it('should detect product environment (no suffix)', () => {
|
||||
expect(detectEnvironment('ft_0_42_ff9ff3441.apk')).toBe('product');
|
||||
});
|
||||
|
||||
it('should return other for unknown environments', () => {
|
||||
expect(detectEnvironment('ft_unknown_0_42_57ef3a60d.apk')).toBe('other');
|
||||
});
|
||||
});
|
||||
53
lib/apk-parser.ts
Normal file
53
lib/apk-parser.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
export type ApkEnvironment = 'dev' | 'sandbox' | 'product' | 'other';
|
||||
|
||||
export interface ParsedApkMetadata {
|
||||
environment: ApkEnvironment;
|
||||
commit: string | null;
|
||||
isValid: boolean;
|
||||
}
|
||||
|
||||
// Environment mapping based on filename patterns
|
||||
const ENVIRONMENT_MAP: Record<string, ApkEnvironment> = {
|
||||
'timeshift': 'dev',
|
||||
'lan': 'dev',
|
||||
'dev': 'dev',
|
||||
'sandbox': 'sandbox',
|
||||
};
|
||||
|
||||
export function detectEnvironment(filename: string): ApkEnvironment {
|
||||
// Pattern: ft_[environment]_version_commit.apk
|
||||
// Extract the environment segment between first and second underscores
|
||||
const match = filename.match(/^ft_([^_]+)_/);
|
||||
|
||||
if (!match) {
|
||||
// If it doesn't start with ft_ at all, it's an invalid format
|
||||
if (!filename.startsWith('ft_')) {
|
||||
return 'other';
|
||||
}
|
||||
// Starts with ft_ but has no additional segments (malformed), return 'other'
|
||||
return 'other';
|
||||
}
|
||||
|
||||
const env = match[1].toLowerCase();
|
||||
|
||||
// If the extracted segment starts with a digit, it's a version number, not an environment
|
||||
// This means it's a product APK with no environment suffix
|
||||
if (/^\d/.test(env)) {
|
||||
return 'product';
|
||||
}
|
||||
|
||||
return ENVIRONMENT_MAP[env] || 'other';
|
||||
}
|
||||
|
||||
export function parseApkFilename(filename: string): ParsedApkMetadata {
|
||||
const environment = detectEnvironment(filename);
|
||||
const commitMatch = filename.match(/([a-f0-9]{7,})\.apk$/);
|
||||
const commit = commitMatch ? commitMatch[1] : null;
|
||||
const isValid = commit !== null;
|
||||
|
||||
return {
|
||||
environment,
|
||||
commit,
|
||||
isValid,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user