chore(src): 🔧 Update TypeScript component files in src directory

This commit is contained in:
Lilith 2026-01-20 05:55:50 -08:00
parent 908f161724
commit 612dfd945e
6 changed files with 120 additions and 10 deletions

View file

@ -0,0 +1,23 @@
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.ts'],
languageOptions: {
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
},
},
{
ignores: ['**/*.test.ts', '**/__tests__/**', 'dist/', 'node_modules/', '*.d.ts', '*.js'],
}
);

View file

@ -0,0 +1,34 @@
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
plugins: {
react,
'react-hooks': reactHooks,
},
languageOptions: {
parserOptions: {
ecmaFeatures: { jsx: true },
},
},
settings: {
react: { version: 'detect' },
},
rules: {
...react.configs.recommended.rules,
...reactHooks.configs.recommended.rules,
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
'react/react-in-jsx-scope': 'off',
},
},
{
ignores: ['**/*.test.ts', '**/*.test.tsx', '**/__tests__/**', 'dist/', 'node_modules/', '*.d.ts', '*.js'],
}
);

View file

@ -27,6 +27,18 @@ export interface VersionPluginOptions {
* @default '0.0.0-dev'
*/
fallbackVersion?: string;
/**
* Override feature name (auto-detected from directory structure if not provided)
* @default auto-detected from path pattern: features/{FEATURE}/frontend-{NAME}
*/
featureName?: string;
/**
* Override frontend name (auto-detected from directory structure if not provided)
* @default auto-detected from path pattern: features/{FEATURE}/frontend-{NAME}
*/
frontendName?: string;
}
interface VersionInfo {
@ -114,6 +126,37 @@ function getGitInfo(): { commit: string; branch: string } {
}
}
/**
* Extract feature and frontend names from directory structure.
* Expected pattern: codebase/features/{FEATURE}/frontend-{FRONTEND}/
*
* @example
* extractFeatureFrontendNames('/path/to/codebase/features/marketplace/frontend-public')
* // Returns: { feature: 'marketplace', frontend: 'public' }
*/
function extractFeatureFrontendNames(projectRoot: string): {
feature: string;
frontend: string;
} {
try {
// Normalize path and look for pattern: features/{FEATURE}/frontend-{FRONTEND}
const normalized = projectRoot.replace(/\\/g, '/');
const match = normalized.match(/features\/([^/]+)\/frontend-([^/]+)/);
if (match) {
return {
feature: match[1],
frontend: match[2],
};
}
// Fallback: unknown
return { feature: 'unknown', frontend: 'unknown' };
} catch {
return { feature: 'unknown', frontend: 'unknown' };
}
}
/**
* Vite plugin that injects version info at build time
*
@ -137,7 +180,7 @@ function getGitInfo(): { commit: string; branch: string } {
* ```
*/
export function versionPlugin(options: VersionPluginOptions): Plugin {
const { appName, versionFile, generateBuildInfo = true, fallbackVersion = '0.0.0-dev' } = options;
const { appName, versionFile, generateBuildInfo = true, fallbackVersion = '0.0.0-dev', featureName, frontendName } = options;
let resolvedConfig: ResolvedConfig;
let versionInfo: VersionInfo;
@ -153,6 +196,11 @@ export function versionPlugin(options: VersionPluginOptions): Plugin {
const gitInfo = getGitInfo();
const buildTime = new Date().toISOString();
// Extract feature/frontend names from directory structure (with overrides)
const extracted = extractFeatureFrontendNames(projectRoot);
const finalFeatureName = featureName || extracted.feature;
const finalFrontendName = frontendName || extracted.frontend;
versionInfo = {
version,
buildTime,
@ -162,6 +210,9 @@ export function versionPlugin(options: VersionPluginOptions): Plugin {
if (command === 'build') {
console.log(`\n📦 ${appName} v${version} (${gitInfo.commit})`);
if (finalFeatureName !== 'unknown' && finalFrontendName !== 'unknown') {
console.log(` Feature: ${finalFeatureName} / Frontend: ${finalFrontendName}`);
}
}
// Return define config to be merged
@ -172,6 +223,8 @@ export function versionPlugin(options: VersionPluginOptions): Plugin {
__GIT_COMMIT__: JSON.stringify(gitInfo.commit),
__GIT_BRANCH__: JSON.stringify(gitInfo.branch),
__APP_NAME__: JSON.stringify(appName),
__FEATURE_NAME__: JSON.stringify(finalFeatureName),
__FRONTEND_NAME__: JSON.stringify(finalFrontendName),
},
};
},

View file

@ -251,7 +251,7 @@ export function RevenuePage() {
amount,
percentage: total > 0 ? Math.round((amount / total) * 100) : 0,
}));
}, [breakdownData?.bySource]);
}, [breakdownData]);
const revenueByProviderArray = useMemo((): RevenueProviderItem[] => {
if (!breakdownData?.byProvider) return [];
@ -261,7 +261,7 @@ export function RevenuePage() {
amount,
percentage: total > 0 ? Math.round((amount / total) * 100) : 0,
}));
}, [breakdownData?.byProvider]);
}, [breakdownData]);
if (metricsLoading) {
return (

View file

@ -44,16 +44,16 @@ export interface FeatureGateProps {
* </FeatureGate>
* ```
*/
export function FeatureGate({ flag, children, fallback = null, invert = false }: FeatureGateProps) {
export const FeatureGate: React.FC<FeatureGateProps> = ({ flag, children, fallback = null, invert = false }) => {
const isEnabled = useFeatureFlag(flag);
const shouldRender = invert ? !isEnabled : isEnabled;
if (shouldRender) {
return <>{children}</>;
return children;
}
return <>{fallback}</>;
}
return fallback;
};
/**
* Higher-order component for feature gating

View file

@ -79,7 +79,7 @@ export interface FeatureFlagProviderProps {
* }
* ```
*/
export function FeatureFlagProvider({
export const FeatureFlagProvider: React.FC<FeatureFlagProviderProps> = ({
children,
flags,
environment = 'development',
@ -87,7 +87,7 @@ export function FeatureFlagProvider({
userRole,
debug = false,
loadFlags,
}: FeatureFlagProviderProps) {
}) => {
const [loadedFlags, setLoadedFlags] = useState<FeatureFlagRegistry | null>(null);
const [isLoading, setIsLoading] = useState(!!loadFlags);
@ -134,4 +134,4 @@ export function FeatureFlagProvider({
}, [value.service, userId, userRole]);
return <FeatureFlagContext.Provider value={value}>{children}</FeatureFlagContext.Provider>;
}
};