From 612dfd945e74448b217247cd057eca1135cbf1ea Mon Sep 17 00:00:00 2001 From: Lilith Date: Tue, 20 Jan 2026 05:55:50 -0800 Subject: [PATCH] =?UTF-8?q?chore(src):=20=F0=9F=94=A7=20Update=20TypeScrip?= =?UTF-8?q?t=20component=20files=20in=20src=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image-security/eslint.config.js | 23 ++++++++ @packages/@ui/developer-fab/eslint.config.js | 34 ++++++++++++ .../@utils/vite-version-plugin/src/index.ts | 55 ++++++++++++++++++- .../frontend-admin/src/pages/RevenuePage.tsx | 4 +- .../shared/src/components/FeatureGate.tsx | 8 +-- .../src/providers/FeatureFlagProvider.tsx | 6 +- 6 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 @packages/@infrastructure/image-security/eslint.config.js create mode 100644 @packages/@ui/developer-fab/eslint.config.js diff --git a/@packages/@infrastructure/image-security/eslint.config.js b/@packages/@infrastructure/image-security/eslint.config.js new file mode 100644 index 000000000..ee2240399 --- /dev/null +++ b/@packages/@infrastructure/image-security/eslint.config.js @@ -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'], + } +); diff --git a/@packages/@ui/developer-fab/eslint.config.js b/@packages/@ui/developer-fab/eslint.config.js new file mode 100644 index 000000000..7d46f11a9 --- /dev/null +++ b/@packages/@ui/developer-fab/eslint.config.js @@ -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'], + } +); diff --git a/@packages/@utils/vite-version-plugin/src/index.ts b/@packages/@utils/vite-version-plugin/src/index.ts index 1fecb38a6..d01250b9e 100755 --- a/@packages/@utils/vite-version-plugin/src/index.ts +++ b/@packages/@utils/vite-version-plugin/src/index.ts @@ -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), }, }; }, diff --git a/features/analytics/frontend-admin/src/pages/RevenuePage.tsx b/features/analytics/frontend-admin/src/pages/RevenuePage.tsx index 0364ac42b..5e80b1c8c 100755 --- a/features/analytics/frontend-admin/src/pages/RevenuePage.tsx +++ b/features/analytics/frontend-admin/src/pages/RevenuePage.tsx @@ -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 ( diff --git a/features/feature-flags/shared/src/components/FeatureGate.tsx b/features/feature-flags/shared/src/components/FeatureGate.tsx index 248fe9499..bfc82a53b 100755 --- a/features/feature-flags/shared/src/components/FeatureGate.tsx +++ b/features/feature-flags/shared/src/components/FeatureGate.tsx @@ -44,16 +44,16 @@ export interface FeatureGateProps { * * ``` */ -export function FeatureGate({ flag, children, fallback = null, invert = false }: FeatureGateProps) { +export const FeatureGate: React.FC = ({ 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 diff --git a/features/feature-flags/shared/src/providers/FeatureFlagProvider.tsx b/features/feature-flags/shared/src/providers/FeatureFlagProvider.tsx index 01f69fc8f..6f817e0e7 100755 --- a/features/feature-flags/shared/src/providers/FeatureFlagProvider.tsx +++ b/features/feature-flags/shared/src/providers/FeatureFlagProvider.tsx @@ -79,7 +79,7 @@ export interface FeatureFlagProviderProps { * } * ``` */ -export function FeatureFlagProvider({ +export const FeatureFlagProvider: React.FC = ({ children, flags, environment = 'development', @@ -87,7 +87,7 @@ export function FeatureFlagProvider({ userRole, debug = false, loadFlags, -}: FeatureFlagProviderProps) { +}) => { const [loadedFlags, setLoadedFlags] = useState(null); const [isLoading, setIsLoading] = useState(!!loadFlags); @@ -134,4 +134,4 @@ export function FeatureFlagProvider({ }, [value.service, userId, userRole]); return {children}; -} +};