@hua-labs/hua-ux 0.1.0-alpha.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +839 -0
- package/dist/framework/a11y/components/LiveRegion.d.ts +64 -0
- package/dist/framework/a11y/components/LiveRegion.d.ts.map +1 -0
- package/dist/framework/a11y/components/LiveRegion.js +43 -0
- package/dist/framework/a11y/components/SkipToContent.d.ts +62 -0
- package/dist/framework/a11y/components/SkipToContent.d.ts.map +1 -0
- package/dist/framework/a11y/components/SkipToContent.js +60 -0
- package/dist/framework/a11y/hooks/useFocusManagement.d.ts +60 -0
- package/dist/framework/a11y/hooks/useFocusManagement.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useFocusManagement.js +71 -0
- package/dist/framework/a11y/hooks/useFocusTrap.d.ts +64 -0
- package/dist/framework/a11y/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useFocusTrap.js +185 -0
- package/dist/framework/a11y/hooks/useLiveRegion.d.ts +56 -0
- package/dist/framework/a11y/hooks/useLiveRegion.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useLiveRegion.js +60 -0
- package/dist/framework/a11y/index.d.ts +16 -0
- package/dist/framework/a11y/index.d.ts.map +1 -0
- package/dist/framework/a11y/index.js +11 -0
- package/dist/framework/branding/context.d.ts +52 -0
- package/dist/framework/branding/context.d.ts.map +1 -0
- package/dist/framework/branding/context.js +96 -0
- package/dist/framework/branding/css-vars.d.ts +34 -0
- package/dist/framework/branding/css-vars.d.ts.map +1 -0
- package/dist/framework/branding/css-vars.js +95 -0
- package/dist/framework/branding/tailwind-config.d.ts +38 -0
- package/dist/framework/branding/tailwind-config.d.ts.map +1 -0
- package/dist/framework/branding/tailwind-config.js +66 -0
- package/dist/framework/components/BrandedButton.d.ts +53 -0
- package/dist/framework/components/BrandedButton.d.ts.map +1 -0
- package/dist/framework/components/BrandedButton.js +40 -0
- package/dist/framework/components/BrandedCard.d.ts +52 -0
- package/dist/framework/components/BrandedCard.d.ts.map +1 -0
- package/dist/framework/components/BrandedCard.js +73 -0
- package/dist/framework/components/ErrorBoundary.d.ts +92 -0
- package/dist/framework/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/framework/components/ErrorBoundary.js +121 -0
- package/dist/framework/components/HuaUxLayout.d.ts +29 -0
- package/dist/framework/components/HuaUxLayout.d.ts.map +1 -0
- package/dist/framework/components/HuaUxLayout.js +32 -0
- package/dist/framework/components/HuaUxPage.d.ts +48 -0
- package/dist/framework/components/HuaUxPage.d.ts.map +1 -0
- package/dist/framework/components/HuaUxPage.js +105 -0
- package/dist/framework/components/Providers.d.ts +17 -0
- package/dist/framework/components/Providers.d.ts.map +1 -0
- package/dist/framework/components/Providers.js +72 -0
- package/dist/framework/components/WelcomePage.d.ts +44 -0
- package/dist/framework/components/WelcomePage.d.ts.map +1 -0
- package/dist/framework/components/WelcomePage.js +80 -0
- package/dist/framework/config/index.d.ts +182 -0
- package/dist/framework/config/index.d.ts.map +1 -0
- package/dist/framework/config/index.js +329 -0
- package/dist/framework/config/merge.d.ts +26 -0
- package/dist/framework/config/merge.d.ts.map +1 -0
- package/dist/framework/config/merge.js +160 -0
- package/dist/framework/config/schema.d.ts +25 -0
- package/dist/framework/config/schema.d.ts.map +1 -0
- package/dist/framework/config/schema.js +122 -0
- package/dist/framework/hooks/useMotion.d.ts +45 -0
- package/dist/framework/hooks/useMotion.d.ts.map +1 -0
- package/dist/framework/hooks/useMotion.js +40 -0
- package/dist/framework/index.d.ts +37 -0
- package/dist/framework/index.d.ts.map +1 -0
- package/dist/framework/index.js +42 -0
- package/dist/framework/license/errors.d.ts +15 -0
- package/dist/framework/license/errors.d.ts.map +1 -0
- package/dist/framework/license/errors.js +52 -0
- package/dist/framework/license/index.d.ts +70 -0
- package/dist/framework/license/index.d.ts.map +1 -0
- package/dist/framework/license/index.js +124 -0
- package/dist/framework/license/loader.d.ts +26 -0
- package/dist/framework/license/loader.d.ts.map +1 -0
- package/dist/framework/license/loader.js +137 -0
- package/dist/framework/license/types.d.ts +67 -0
- package/dist/framework/license/types.d.ts.map +1 -0
- package/dist/framework/license/types.js +18 -0
- package/dist/framework/loading/components/SkeletonGroup.d.ts +44 -0
- package/dist/framework/loading/components/SkeletonGroup.d.ts.map +1 -0
- package/dist/framework/loading/components/SkeletonGroup.js +34 -0
- package/dist/framework/loading/components/SuspenseWrapper.d.ts +58 -0
- package/dist/framework/loading/components/SuspenseWrapper.d.ts.map +1 -0
- package/dist/framework/loading/components/SuspenseWrapper.js +40 -0
- package/dist/framework/loading/hoc/withSuspense.d.ts +46 -0
- package/dist/framework/loading/hoc/withSuspense.d.ts.map +1 -0
- package/dist/framework/loading/hoc/withSuspense.js +54 -0
- package/dist/framework/loading/hooks/useDelayedLoading.d.ts +56 -0
- package/dist/framework/loading/hooks/useDelayedLoading.d.ts.map +1 -0
- package/dist/framework/loading/hooks/useDelayedLoading.js +97 -0
- package/dist/framework/loading/hooks/useLoadingState.d.ts +69 -0
- package/dist/framework/loading/hooks/useLoadingState.d.ts.map +1 -0
- package/dist/framework/loading/hooks/useLoadingState.js +59 -0
- package/dist/framework/loading/index.d.ts +16 -0
- package/dist/framework/loading/index.d.ts.map +1 -0
- package/dist/framework/loading/index.js +13 -0
- package/dist/framework/middleware/i18n.d.ts +90 -0
- package/dist/framework/middleware/i18n.d.ts.map +1 -0
- package/dist/framework/middleware/i18n.js +99 -0
- package/dist/framework/plugins/index.d.ts +8 -0
- package/dist/framework/plugins/index.d.ts.map +1 -0
- package/dist/framework/plugins/index.js +6 -0
- package/dist/framework/plugins/registry.d.ts +95 -0
- package/dist/framework/plugins/registry.d.ts.map +1 -0
- package/dist/framework/plugins/registry.js +160 -0
- package/dist/framework/plugins/types.d.ts +97 -0
- package/dist/framework/plugins/types.d.ts.map +1 -0
- package/dist/framework/plugins/types.js +6 -0
- package/dist/framework/seo/geo/examples.d.ts +87 -0
- package/dist/framework/seo/geo/examples.d.ts.map +1 -0
- package/dist/framework/seo/geo/examples.js +295 -0
- package/dist/framework/seo/geo/generateGEOMetadata.d.ts +107 -0
- package/dist/framework/seo/geo/generateGEOMetadata.d.ts.map +1 -0
- package/dist/framework/seo/geo/generateGEOMetadata.js +404 -0
- package/dist/framework/seo/geo/index.d.ts +19 -0
- package/dist/framework/seo/geo/index.d.ts.map +1 -0
- package/dist/framework/seo/geo/index.js +21 -0
- package/dist/framework/seo/geo/presets.d.ts +52 -0
- package/dist/framework/seo/geo/presets.d.ts.map +1 -0
- package/dist/framework/seo/geo/presets.js +47 -0
- package/dist/framework/seo/geo/structuredData.d.ts +187 -0
- package/dist/framework/seo/geo/structuredData.d.ts.map +1 -0
- package/dist/framework/seo/geo/structuredData.js +354 -0
- package/dist/framework/seo/geo/test-utils.d.ts +78 -0
- package/dist/framework/seo/geo/test-utils.d.ts.map +1 -0
- package/dist/framework/seo/geo/test-utils.js +139 -0
- package/dist/framework/seo/geo/types.d.ts +225 -0
- package/dist/framework/seo/geo/types.d.ts.map +1 -0
- package/dist/framework/seo/geo/types.js +51 -0
- package/dist/framework/types/index.d.ts +577 -0
- package/dist/framework/types/index.d.ts.map +1 -0
- package/dist/framework/types/index.js +6 -0
- package/dist/framework/utils/data-fetching.d.ts +45 -0
- package/dist/framework/utils/data-fetching.d.ts.map +1 -0
- package/dist/framework/utils/data-fetching.js +74 -0
- package/dist/framework/utils/file-structure.d.ts +29 -0
- package/dist/framework/utils/file-structure.d.ts.map +1 -0
- package/dist/framework/utils/file-structure.js +72 -0
- package/dist/framework/utils/metadata.d.ts +109 -0
- package/dist/framework/utils/metadata.d.ts.map +1 -0
- package/dist/framework/utils/metadata.js +105 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/presets/index.d.ts +8 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +7 -0
- package/dist/presets/marketing.d.ts +41 -0
- package/dist/presets/marketing.d.ts.map +1 -0
- package/dist/presets/marketing.js +81 -0
- package/dist/presets/product.d.ts +41 -0
- package/dist/presets/product.d.ts.map +1 -0
- package/dist/presets/product.js +74 -0
- package/package.json +91 -0
- package/src/framework/README.md +329 -0
- package/src/framework/__tests__/branding/css-vars.test.ts +147 -0
- package/src/framework/__tests__/components/ErrorBoundary.test.tsx +146 -0
- package/src/framework/__tests__/config/defineConfig.test.ts +138 -0
- package/src/framework/__tests__/hooks/useMotion.test.ts +105 -0
- package/src/framework/__tests__/seo/geo/generateGEOMetadata.test.ts +207 -0
- package/src/framework/__tests__/seo/geo/structuredData.test.ts +262 -0
- package/src/framework/a11y/components/LiveRegion.tsx +89 -0
- package/src/framework/a11y/components/SkipToContent.tsx +103 -0
- package/src/framework/a11y/hooks/useFocusManagement.ts +125 -0
- package/src/framework/a11y/hooks/useFocusTrap.ts +239 -0
- package/src/framework/a11y/hooks/useLiveRegion.ts +95 -0
- package/src/framework/a11y/index.ts +17 -0
- package/src/framework/branding/context.tsx +135 -0
- package/src/framework/branding/css-vars.ts +110 -0
- package/src/framework/branding/tailwind-config.ts +90 -0
- package/src/framework/components/BrandedButton.tsx +94 -0
- package/src/framework/components/BrandedCard.tsx +87 -0
- package/src/framework/components/ErrorBoundary.tsx +215 -0
- package/src/framework/components/HuaUxLayout.tsx +36 -0
- package/src/framework/components/HuaUxPage.tsx +138 -0
- package/src/framework/components/Providers.tsx +98 -0
- package/src/framework/components/WelcomePage.tsx +207 -0
- package/src/framework/config/index.ts +349 -0
- package/src/framework/config/merge.ts +190 -0
- package/src/framework/config/schema.ts +140 -0
- package/src/framework/hooks/useMotion.ts +57 -0
- package/src/framework/index.ts +122 -0
- package/src/framework/license/errors.ts +63 -0
- package/src/framework/license/index.ts +137 -0
- package/src/framework/license/loader.ts +158 -0
- package/src/framework/license/types.ts +95 -0
- package/src/framework/loading/components/SkeletonGroup.tsx +70 -0
- package/src/framework/loading/components/SuspenseWrapper.tsx +88 -0
- package/src/framework/loading/hoc/withSuspense.tsx +96 -0
- package/src/framework/loading/hooks/useDelayedLoading.ts +127 -0
- package/src/framework/loading/hooks/useLoadingState.ts +103 -0
- package/src/framework/loading/index.ts +19 -0
- package/src/framework/middleware/i18n.ts +161 -0
- package/src/framework/middleware/index.ts +7 -0
- package/src/framework/plugins/index.ts +13 -0
- package/src/framework/plugins/registry.ts +186 -0
- package/src/framework/plugins/types.ts +106 -0
- package/src/framework/seo/geo/examples.tsx +415 -0
- package/src/framework/seo/geo/generateGEOMetadata.ts +441 -0
- package/src/framework/seo/geo/index.ts +61 -0
- package/src/framework/seo/geo/presets.ts +58 -0
- package/src/framework/seo/geo/structuredData.ts +422 -0
- package/src/framework/seo/geo/test-utils.ts +179 -0
- package/src/framework/seo/geo/types.ts +315 -0
- package/src/framework/types/index.ts +623 -0
- package/src/framework/utils/data-fetching.ts +95 -0
- package/src/framework/utils/file-structure.ts +88 -0
- package/src/framework/utils/metadata.ts +152 -0
- package/src/index.ts +31 -0
- package/src/presets/index.ts +8 -0
- package/src/presets/marketing.ts +88 -0
- package/src/presets/product.ts +81 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - WelcomePage
|
|
3
|
+
*
|
|
4
|
+
* Default welcome page component for new projects
|
|
5
|
+
* Similar to Next.js default welcome page
|
|
6
|
+
*/
|
|
7
|
+
'use client';
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { HuaUxPage } from './HuaUxPage';
|
|
10
|
+
import { Button, Card, Badge } from '@hua-labs/ui';
|
|
11
|
+
import { useTranslation } from '@hua-labs/i18n-core';
|
|
12
|
+
/**
|
|
13
|
+
* WelcomePage Component
|
|
14
|
+
*
|
|
15
|
+
* Default welcome page for new hua-ux projects.
|
|
16
|
+
* Displays project information, framework features, and quick links.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* // app/page.tsx
|
|
21
|
+
* import { WelcomePage } from '@hua-labs/hua-ux/framework';
|
|
22
|
+
*
|
|
23
|
+
* export default function HomePage() {
|
|
24
|
+
* return <WelcomePage projectName="My App" />;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function WelcomePage({ projectName = 'My App', showFeatures = true, showQuickLinks = true, children, ...pageProps }) {
|
|
29
|
+
const { t, currentLanguage } = useTranslation();
|
|
30
|
+
const features = [
|
|
31
|
+
{
|
|
32
|
+
title: t('features.ui.title', 'UI Components'),
|
|
33
|
+
description: t('features.ui.description', 'Pre-built, accessible components'),
|
|
34
|
+
icon: '🎨',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
title: t('features.i18n.title', 'i18n Support'),
|
|
38
|
+
description: t('features.i18n.description', 'Multi-language support out of the box'),
|
|
39
|
+
icon: '🌐',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
title: t('features.motion.title', 'Motion'),
|
|
43
|
+
description: t('features.motion.description', 'Smooth animations and transitions'),
|
|
44
|
+
icon: '✨',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: t('features.ai.title', 'AI-First'),
|
|
48
|
+
description: t('features.ai.description', 'Built for vibe coding with AI'),
|
|
49
|
+
icon: '🤖',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
const quickLinks = [
|
|
53
|
+
{
|
|
54
|
+
title: t('links.docs.title', 'Documentation'),
|
|
55
|
+
description: t('links.docs.description', 'Learn more about hua-ux'),
|
|
56
|
+
href: 'https://github.com/HUA-Labs/HUA-Labs-public',
|
|
57
|
+
external: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: t('links.examples.title', 'Examples'),
|
|
61
|
+
description: t('links.examples.description', 'See examples and patterns'),
|
|
62
|
+
href: '/examples',
|
|
63
|
+
external: false,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
title: t('links.github.title', 'GitHub'),
|
|
67
|
+
description: t('links.github.description', 'View source code'),
|
|
68
|
+
href: 'https://github.com/HUA-Labs/HUA-Labs-public',
|
|
69
|
+
external: true,
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
return (_jsx(HuaUxPage, { title: t('welcome.title', 'Welcome'), description: t('welcome.description', `Get started by editing app/page.tsx`), vibe: "clean", ...pageProps, children: _jsx("div", { className: "min-h-screen flex flex-col items-center justify-center p-8 bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800", children: _jsxs("div", { className: "max-w-4xl w-full space-y-8", children: [_jsxs("div", { className: "text-center space-y-4", children: [_jsxs("div", { className: "flex items-center justify-center gap-3", children: [_jsx("h1", { className: "text-5xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent", children: projectName }), _jsx(Badge, { variant: "secondary", className: "text-sm", children: t('badge.alpha', 'Alpha') })] }), _jsx("p", { className: "text-xl text-gray-600 dark:text-gray-400", children: t('welcome.subtitle', 'Built with @hua-labs/hua-ux') }), _jsx("p", { className: "text-gray-500 dark:text-gray-500", children: t('welcome.description', 'Get started by editing app/page.tsx') })] }), children && (_jsx("div", { className: "flex justify-center", children: children })), showFeatures && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: features.map((feature, index) => (_jsx(Card, { className: "p-6 hover:shadow-lg transition-shadow cursor-pointer", children: _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-3xl mb-2", children: feature.icon }), _jsx("h3", { className: "font-semibold text-lg", children: feature.title }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: feature.description })] }) }, index))) })), showQuickLinks && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: quickLinks.map((link, index) => (_jsx(Card, { className: "p-6 hover:shadow-lg transition-shadow", children: _jsxs("div", { className: "space-y-2", children: [_jsx("h3", { className: "font-semibold text-lg", children: link.title }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: link.description }), _jsxs(Button, { variant: "outline", size: "sm", className: "mt-4", onClick: () => {
|
|
73
|
+
if (link.external) {
|
|
74
|
+
window.open(link.href, '_blank', 'noopener,noreferrer');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
window.location.href = link.href;
|
|
78
|
+
}
|
|
79
|
+
}, children: [t('links.visit', 'Visit'), " \u2192"] })] }) }, index))) })), _jsxs("div", { className: "text-center text-sm text-gray-500 dark:text-gray-400 space-y-2", children: [_jsxs("p", { children: [t('footer.language', 'Language'), ": ", _jsx("strong", { children: currentLanguage })] }), _jsxs("p", { children: [t('footer.framework', 'Framework'), ": ", _jsx("strong", { children: "@hua-labs/hua-ux" })] })] })] }) }) }));
|
|
80
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Config System
|
|
3
|
+
*
|
|
4
|
+
* Configuration loading and management
|
|
5
|
+
*/
|
|
6
|
+
import type { HuaUxConfig } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* 프레임워크 설정 정의 / Define framework configuration
|
|
9
|
+
*
|
|
10
|
+
* IntelliSense를 완벽히 지원하는 설정 함수입니다.
|
|
11
|
+
* Provides full IntelliSense support for configuration options.
|
|
12
|
+
*
|
|
13
|
+
* 모든 옵션은 선택사항이며 기본값 또는 Preset과 병합됩니다.
|
|
14
|
+
* All options are optional and will be merged with defaults or Preset.
|
|
15
|
+
*
|
|
16
|
+
* **Zero-Config**: 설정 파일이 없어도 기본값으로 동작합니다.
|
|
17
|
+
* **Zero-Config**: Works with defaults even without a config file.
|
|
18
|
+
*
|
|
19
|
+
* **Preset 우선**: `preset: 'product'`만 지정해도 대부분의 설정이 자동 적용됩니다.
|
|
20
|
+
* **Preset First**: Just specify `preset: 'product'` and most settings are auto-applied.
|
|
21
|
+
*
|
|
22
|
+
* **바이브 코딩 친화적**: AI가 이해하기 쉬운 한글 주석과 명사 중심 설정
|
|
23
|
+
* **Vibe Coding Friendly**: Korean comments and noun-centered settings for AI understanding
|
|
24
|
+
*
|
|
25
|
+
* @param config - 설정 객체 / Configuration object
|
|
26
|
+
* @param config.preset - 사용할 프리셋 / Preset to use
|
|
27
|
+
* - **바이브 모드 (간단) / Vibe mode (simple)**: `'product' | 'marketing'`
|
|
28
|
+
* - 'product': 제품 페이지용 (전문적, 효율적, 기본값) / Product pages (professional, efficient, default)
|
|
29
|
+
* - 'marketing': 마케팅 페이지용 (화려함, 눈에 띄는) / Marketing pages (dramatic, eye-catching)
|
|
30
|
+
* - **개발자 모드 (세부 설정) / Developer mode (detailed)**: `{ type: 'product' | 'marketing', motion?: {...}, spacing?: {...} }`
|
|
31
|
+
* - 세부 설정을 포함한 Preset 객체 / Preset object with detailed settings
|
|
32
|
+
* - Preset을 선택하면 motion, spacing, i18n 등이 자동 설정됩니다.
|
|
33
|
+
* - Selecting a preset automatically configures motion, spacing, i18n, etc.
|
|
34
|
+
* @param config.i18n - 다국어 설정 / Internationalization settings
|
|
35
|
+
* @param config.i18n.defaultLanguage - 기본 언어 코드 (예: 'ko', 'en') / Default language code (e.g., 'ko', 'en')
|
|
36
|
+
* @param config.i18n.supportedLanguages - 지원하는 언어 코드 배열 / Array of supported language codes
|
|
37
|
+
* @param config.i18n.namespaces - 로드할 번역 네임스페이스 / Translation namespaces to load
|
|
38
|
+
* @param config.i18n.translationLoader - 번역 로딩 전략 ('static' | 'api') / Translation loading strategy
|
|
39
|
+
* @param config.i18n.translationApiPath - 번역 API 경로 ('api' 로더 사용 시) / API path for translations
|
|
40
|
+
* @param config.motion - 모션/애니메이션 설정 / Motion/animation settings
|
|
41
|
+
* @param config.motion.style - 모션 스타일 (바이브 코더용) / Motion style (for vibe coders)
|
|
42
|
+
* - 'smooth': 부드러운 전환 / Smooth transitions
|
|
43
|
+
* - 'dramatic': 드라마틱한 전환 / Dramatic transitions
|
|
44
|
+
* - 'minimal': 최소한의 전환 / Minimal transitions
|
|
45
|
+
* @param config.motion.defaultPreset - 기본 모션 프리셋 (개발자용) / Default motion preset (for developers)
|
|
46
|
+
* - 'product': 빠른 전환, 최소 딜레이 / Fast transitions, minimal delay
|
|
47
|
+
* - 'marketing': 느린 전환, 긴 딜레이 / Slow transitions, long delay
|
|
48
|
+
* @param config.motion.enableAnimations - 전역 애니메이션 활성화 여부 / Enable animations globally
|
|
49
|
+
* @param config.motion.duration - 애니메이션 지속 시간 (밀리초, 개발자용) / Animation duration in milliseconds (for developers)
|
|
50
|
+
* @param config.motion.easing - 애니메이션 이징 함수 (개발자용) / Animation easing function (for developers)
|
|
51
|
+
* @param config.state - 상태 관리 설정 / State management settings
|
|
52
|
+
* @param config.state.persist - localStorage 영속성 활성화 여부 / Enable localStorage persistence
|
|
53
|
+
* @param config.state.ssr - SSR 지원 활성화 여부 / Enable SSR support
|
|
54
|
+
* @param config.branding - 브랜딩 설정 (화이트 라벨링) / Branding settings (white labeling)
|
|
55
|
+
* @param config.branding.name - 회사/서비스 이름 / Company/service name
|
|
56
|
+
* @param config.branding.logo - 로고 경로 / Logo path
|
|
57
|
+
* @param config.branding.colors - 색상 팔레트 (primary, secondary, accent 등) / Color palette
|
|
58
|
+
* @param config.branding.typography - 타이포그래피 설정 (fontFamily, fontSize 등) / Typography settings
|
|
59
|
+
*
|
|
60
|
+
* @returns 검증된 설정 객체 / Validated configuration object
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* // 최소 설정 (Preset만) - 바이브 코더용
|
|
65
|
+
* // hua-ux.config.ts
|
|
66
|
+
* import { defineConfig } from '@hua-labs/hua-ux/framework';
|
|
67
|
+
*
|
|
68
|
+
* export default defineConfig({
|
|
69
|
+
* preset: 'product', // 끝! 나머지는 자동 설정
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* // Preset + 일부 커스터마이징
|
|
76
|
+
* export default defineConfig({
|
|
77
|
+
* preset: 'product',
|
|
78
|
+
* i18n: {
|
|
79
|
+
* supportedLanguages: ['ko', 'en', 'ja'], // 언어만 추가
|
|
80
|
+
* },
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // 개발자 모드: Preset 객체 형태 (세부 설정)
|
|
87
|
+
* export default defineConfig({
|
|
88
|
+
* preset: {
|
|
89
|
+
* type: 'product',
|
|
90
|
+
* motion: { duration: 300 },
|
|
91
|
+
* spacing: { default: 'md' },
|
|
92
|
+
* },
|
|
93
|
+
* });
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* // 바이브 코더용: motion.style 사용
|
|
99
|
+
* export default defineConfig({
|
|
100
|
+
* preset: 'product',
|
|
101
|
+
* motion: {
|
|
102
|
+
* style: 'smooth', // 명사 중심, 이해하기 쉬움
|
|
103
|
+
* },
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* // 완전 커스터마이징 (Preset 없이) - 전통 개발자용
|
|
110
|
+
* export default defineConfig({
|
|
111
|
+
* i18n: {
|
|
112
|
+
* defaultLanguage: 'ko',
|
|
113
|
+
* supportedLanguages: ['ko', 'en'],
|
|
114
|
+
* namespaces: ['common'],
|
|
115
|
+
* translationLoader: 'api',
|
|
116
|
+
* translationApiPath: '/api/translations',
|
|
117
|
+
* },
|
|
118
|
+
* motion: {
|
|
119
|
+
* defaultPreset: 'product',
|
|
120
|
+
* enableAnimations: true,
|
|
121
|
+
* },
|
|
122
|
+
* state: {
|
|
123
|
+
* persist: true,
|
|
124
|
+
* ssr: true,
|
|
125
|
+
* },
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare function defineConfig(config: Partial<HuaUxConfig>): HuaUxConfig;
|
|
130
|
+
/**
|
|
131
|
+
* Load configuration from file
|
|
132
|
+
*
|
|
133
|
+
* 동적으로 설정 파일을 로드합니다.
|
|
134
|
+
*
|
|
135
|
+
* **로드 순서**:
|
|
136
|
+
* 1. `hua-ux.config.ts` 시도 (TypeScript)
|
|
137
|
+
* 2. `hua-ux.config.js` 시도 (JavaScript)
|
|
138
|
+
* 3. 없으면 기본값 (product preset)
|
|
139
|
+
*
|
|
140
|
+
* **Zero-Config**: 설정 파일이 없어도 기본값으로 동작합니다.
|
|
141
|
+
*
|
|
142
|
+
* **주의사항**:
|
|
143
|
+
* - 이 함수는 Node.js 환경(빌드 타임)에서만 동작합니다.
|
|
144
|
+
* - 런타임에서는 캐시된 설정을 사용합니다.
|
|
145
|
+
* - **권장**: 설정 파일을 명시적으로 import하여 타입 안전성을 보장하세요.
|
|
146
|
+
* ```ts
|
|
147
|
+
* // hua-ux.config.ts
|
|
148
|
+
* import { defineConfig } from '@hua-labs/hua-ux/framework';
|
|
149
|
+
* export default defineConfig({ preset: 'product' });
|
|
150
|
+
*
|
|
151
|
+
* // app/layout.tsx 또는 다른 서버 컴포넌트에서
|
|
152
|
+
* import config from '../hua-ux.config';
|
|
153
|
+
* import { setConfig } from '@hua-labs/hua-ux/framework';
|
|
154
|
+
* setConfig(config);
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* **Fallback 용도**: 이 함수는 설정 파일이 명시적으로 import되지 않은 경우에만 사용됩니다.
|
|
158
|
+
* 프로덕션 환경에서는 설정 파일을 명시적으로 import하는 것을 권장합니다.
|
|
159
|
+
*/
|
|
160
|
+
export declare function loadConfig(): HuaUxConfig;
|
|
161
|
+
/**
|
|
162
|
+
* Get current configuration
|
|
163
|
+
*
|
|
164
|
+
* 캐시된 설정을 반환하거나, 없으면 로드합니다.
|
|
165
|
+
*
|
|
166
|
+
* **클라이언트 안전**: 클라이언트에서는 항상 기본값을 반환합니다.
|
|
167
|
+
* **Client Safe**: Always returns default config on client side.
|
|
168
|
+
*/
|
|
169
|
+
export declare function getConfig(): HuaUxConfig;
|
|
170
|
+
/**
|
|
171
|
+
* Set configuration (for testing or manual override)
|
|
172
|
+
*
|
|
173
|
+
* 테스트나 수동 오버라이드를 위한 설정 설정 함수
|
|
174
|
+
*/
|
|
175
|
+
export declare function setConfig(config: HuaUxConfig): void;
|
|
176
|
+
/**
|
|
177
|
+
* Reset configuration cache
|
|
178
|
+
*
|
|
179
|
+
* 설정 캐시를 초기화합니다. (주로 테스트용)
|
|
180
|
+
*/
|
|
181
|
+
export declare function resetConfig(): void;
|
|
182
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/framework/config/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAU,MAAM,UAAU,CAAC;AAWpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyHG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAyCtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,UAAU,IAAI,WAAW,CA4FxC;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,IAAI,WAAW,CAgBvC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Config System
|
|
3
|
+
*
|
|
4
|
+
* Configuration loading and management
|
|
5
|
+
*/
|
|
6
|
+
import { validateConfig } from './schema';
|
|
7
|
+
import { mergePresetWithConfig, createConfigFromUserConfig } from './merge';
|
|
8
|
+
import { initLicense } from '../license';
|
|
9
|
+
import { pluginRegistry } from '../plugins';
|
|
10
|
+
/**
|
|
11
|
+
* Global config cache
|
|
12
|
+
*/
|
|
13
|
+
let cachedConfig = null;
|
|
14
|
+
/**
|
|
15
|
+
* 프레임워크 설정 정의 / Define framework configuration
|
|
16
|
+
*
|
|
17
|
+
* IntelliSense를 완벽히 지원하는 설정 함수입니다.
|
|
18
|
+
* Provides full IntelliSense support for configuration options.
|
|
19
|
+
*
|
|
20
|
+
* 모든 옵션은 선택사항이며 기본값 또는 Preset과 병합됩니다.
|
|
21
|
+
* All options are optional and will be merged with defaults or Preset.
|
|
22
|
+
*
|
|
23
|
+
* **Zero-Config**: 설정 파일이 없어도 기본값으로 동작합니다.
|
|
24
|
+
* **Zero-Config**: Works with defaults even without a config file.
|
|
25
|
+
*
|
|
26
|
+
* **Preset 우선**: `preset: 'product'`만 지정해도 대부분의 설정이 자동 적용됩니다.
|
|
27
|
+
* **Preset First**: Just specify `preset: 'product'` and most settings are auto-applied.
|
|
28
|
+
*
|
|
29
|
+
* **바이브 코딩 친화적**: AI가 이해하기 쉬운 한글 주석과 명사 중심 설정
|
|
30
|
+
* **Vibe Coding Friendly**: Korean comments and noun-centered settings for AI understanding
|
|
31
|
+
*
|
|
32
|
+
* @param config - 설정 객체 / Configuration object
|
|
33
|
+
* @param config.preset - 사용할 프리셋 / Preset to use
|
|
34
|
+
* - **바이브 모드 (간단) / Vibe mode (simple)**: `'product' | 'marketing'`
|
|
35
|
+
* - 'product': 제품 페이지용 (전문적, 효율적, 기본값) / Product pages (professional, efficient, default)
|
|
36
|
+
* - 'marketing': 마케팅 페이지용 (화려함, 눈에 띄는) / Marketing pages (dramatic, eye-catching)
|
|
37
|
+
* - **개발자 모드 (세부 설정) / Developer mode (detailed)**: `{ type: 'product' | 'marketing', motion?: {...}, spacing?: {...} }`
|
|
38
|
+
* - 세부 설정을 포함한 Preset 객체 / Preset object with detailed settings
|
|
39
|
+
* - Preset을 선택하면 motion, spacing, i18n 등이 자동 설정됩니다.
|
|
40
|
+
* - Selecting a preset automatically configures motion, spacing, i18n, etc.
|
|
41
|
+
* @param config.i18n - 다국어 설정 / Internationalization settings
|
|
42
|
+
* @param config.i18n.defaultLanguage - 기본 언어 코드 (예: 'ko', 'en') / Default language code (e.g., 'ko', 'en')
|
|
43
|
+
* @param config.i18n.supportedLanguages - 지원하는 언어 코드 배열 / Array of supported language codes
|
|
44
|
+
* @param config.i18n.namespaces - 로드할 번역 네임스페이스 / Translation namespaces to load
|
|
45
|
+
* @param config.i18n.translationLoader - 번역 로딩 전략 ('static' | 'api') / Translation loading strategy
|
|
46
|
+
* @param config.i18n.translationApiPath - 번역 API 경로 ('api' 로더 사용 시) / API path for translations
|
|
47
|
+
* @param config.motion - 모션/애니메이션 설정 / Motion/animation settings
|
|
48
|
+
* @param config.motion.style - 모션 스타일 (바이브 코더용) / Motion style (for vibe coders)
|
|
49
|
+
* - 'smooth': 부드러운 전환 / Smooth transitions
|
|
50
|
+
* - 'dramatic': 드라마틱한 전환 / Dramatic transitions
|
|
51
|
+
* - 'minimal': 최소한의 전환 / Minimal transitions
|
|
52
|
+
* @param config.motion.defaultPreset - 기본 모션 프리셋 (개발자용) / Default motion preset (for developers)
|
|
53
|
+
* - 'product': 빠른 전환, 최소 딜레이 / Fast transitions, minimal delay
|
|
54
|
+
* - 'marketing': 느린 전환, 긴 딜레이 / Slow transitions, long delay
|
|
55
|
+
* @param config.motion.enableAnimations - 전역 애니메이션 활성화 여부 / Enable animations globally
|
|
56
|
+
* @param config.motion.duration - 애니메이션 지속 시간 (밀리초, 개발자용) / Animation duration in milliseconds (for developers)
|
|
57
|
+
* @param config.motion.easing - 애니메이션 이징 함수 (개발자용) / Animation easing function (for developers)
|
|
58
|
+
* @param config.state - 상태 관리 설정 / State management settings
|
|
59
|
+
* @param config.state.persist - localStorage 영속성 활성화 여부 / Enable localStorage persistence
|
|
60
|
+
* @param config.state.ssr - SSR 지원 활성화 여부 / Enable SSR support
|
|
61
|
+
* @param config.branding - 브랜딩 설정 (화이트 라벨링) / Branding settings (white labeling)
|
|
62
|
+
* @param config.branding.name - 회사/서비스 이름 / Company/service name
|
|
63
|
+
* @param config.branding.logo - 로고 경로 / Logo path
|
|
64
|
+
* @param config.branding.colors - 색상 팔레트 (primary, secondary, accent 등) / Color palette
|
|
65
|
+
* @param config.branding.typography - 타이포그래피 설정 (fontFamily, fontSize 등) / Typography settings
|
|
66
|
+
*
|
|
67
|
+
* @returns 검증된 설정 객체 / Validated configuration object
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* // 최소 설정 (Preset만) - 바이브 코더용
|
|
72
|
+
* // hua-ux.config.ts
|
|
73
|
+
* import { defineConfig } from '@hua-labs/hua-ux/framework';
|
|
74
|
+
*
|
|
75
|
+
* export default defineConfig({
|
|
76
|
+
* preset: 'product', // 끝! 나머지는 자동 설정
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* // Preset + 일부 커스터마이징
|
|
83
|
+
* export default defineConfig({
|
|
84
|
+
* preset: 'product',
|
|
85
|
+
* i18n: {
|
|
86
|
+
* supportedLanguages: ['ko', 'en', 'ja'], // 언어만 추가
|
|
87
|
+
* },
|
|
88
|
+
* });
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* // 개발자 모드: Preset 객체 형태 (세부 설정)
|
|
94
|
+
* export default defineConfig({
|
|
95
|
+
* preset: {
|
|
96
|
+
* type: 'product',
|
|
97
|
+
* motion: { duration: 300 },
|
|
98
|
+
* spacing: { default: 'md' },
|
|
99
|
+
* },
|
|
100
|
+
* });
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* // 바이브 코더용: motion.style 사용
|
|
106
|
+
* export default defineConfig({
|
|
107
|
+
* preset: 'product',
|
|
108
|
+
* motion: {
|
|
109
|
+
* style: 'smooth', // 명사 중심, 이해하기 쉬움
|
|
110
|
+
* },
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* // 완전 커스터마이징 (Preset 없이) - 전통 개발자용
|
|
117
|
+
* export default defineConfig({
|
|
118
|
+
* i18n: {
|
|
119
|
+
* defaultLanguage: 'ko',
|
|
120
|
+
* supportedLanguages: ['ko', 'en'],
|
|
121
|
+
* namespaces: ['common'],
|
|
122
|
+
* translationLoader: 'api',
|
|
123
|
+
* translationApiPath: '/api/translations',
|
|
124
|
+
* },
|
|
125
|
+
* motion: {
|
|
126
|
+
* defaultPreset: 'product',
|
|
127
|
+
* enableAnimations: true,
|
|
128
|
+
* },
|
|
129
|
+
* state: {
|
|
130
|
+
* persist: true,
|
|
131
|
+
* ssr: true,
|
|
132
|
+
* },
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export function defineConfig(config) {
|
|
137
|
+
// 라이선스 초기화
|
|
138
|
+
if (config.license) {
|
|
139
|
+
initLicense(config.license);
|
|
140
|
+
}
|
|
141
|
+
// 플러그인 등록 및 초기화
|
|
142
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
143
|
+
config.plugins.forEach(plugin => {
|
|
144
|
+
pluginRegistry.register(plugin);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
// Preset이 지정된 경우 Preset과 병합
|
|
148
|
+
if (config.preset) {
|
|
149
|
+
const { preset, ...userConfig } = config;
|
|
150
|
+
const merged = mergePresetWithConfig(preset, userConfig);
|
|
151
|
+
const validated = validateConfig(merged);
|
|
152
|
+
// 플러그인 초기화 (설정이 완료된 후)
|
|
153
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
154
|
+
pluginRegistry.initializeAll(validated).catch((error) => {
|
|
155
|
+
console.error('[hua-ux] Plugin initialization error:', error);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return validated;
|
|
159
|
+
}
|
|
160
|
+
// Preset이 없는 경우 사용자 설정만 사용
|
|
161
|
+
const merged = createConfigFromUserConfig(config);
|
|
162
|
+
const validated = validateConfig(merged);
|
|
163
|
+
// 플러그인 초기화 (설정이 완료된 후)
|
|
164
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
165
|
+
pluginRegistry.initializeAll(validated).catch((error) => {
|
|
166
|
+
console.error('[hua-ux] Plugin initialization error:', error);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return validated;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Load configuration from file
|
|
173
|
+
*
|
|
174
|
+
* 동적으로 설정 파일을 로드합니다.
|
|
175
|
+
*
|
|
176
|
+
* **로드 순서**:
|
|
177
|
+
* 1. `hua-ux.config.ts` 시도 (TypeScript)
|
|
178
|
+
* 2. `hua-ux.config.js` 시도 (JavaScript)
|
|
179
|
+
* 3. 없으면 기본값 (product preset)
|
|
180
|
+
*
|
|
181
|
+
* **Zero-Config**: 설정 파일이 없어도 기본값으로 동작합니다.
|
|
182
|
+
*
|
|
183
|
+
* **주의사항**:
|
|
184
|
+
* - 이 함수는 Node.js 환경(빌드 타임)에서만 동작합니다.
|
|
185
|
+
* - 런타임에서는 캐시된 설정을 사용합니다.
|
|
186
|
+
* - **권장**: 설정 파일을 명시적으로 import하여 타입 안전성을 보장하세요.
|
|
187
|
+
* ```ts
|
|
188
|
+
* // hua-ux.config.ts
|
|
189
|
+
* import { defineConfig } from '@hua-labs/hua-ux/framework';
|
|
190
|
+
* export default defineConfig({ preset: 'product' });
|
|
191
|
+
*
|
|
192
|
+
* // app/layout.tsx 또는 다른 서버 컴포넌트에서
|
|
193
|
+
* import config from '../hua-ux.config';
|
|
194
|
+
* import { setConfig } from '@hua-labs/hua-ux/framework';
|
|
195
|
+
* setConfig(config);
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* **Fallback 용도**: 이 함수는 설정 파일이 명시적으로 import되지 않은 경우에만 사용됩니다.
|
|
199
|
+
* 프로덕션 환경에서는 설정 파일을 명시적으로 import하는 것을 권장합니다.
|
|
200
|
+
*/
|
|
201
|
+
export function loadConfig() {
|
|
202
|
+
if (cachedConfig) {
|
|
203
|
+
return cachedConfig;
|
|
204
|
+
}
|
|
205
|
+
// Node.js 환경에서만 동적 로드 시도 (서버 사이드에서만)
|
|
206
|
+
// 클라이언트에서는 기본 설정 반환
|
|
207
|
+
if (typeof window !== 'undefined') {
|
|
208
|
+
// 브라우저 환경: 기본 설정 반환
|
|
209
|
+
cachedConfig = mergePresetWithConfig('product', {});
|
|
210
|
+
return cachedConfig;
|
|
211
|
+
}
|
|
212
|
+
// Node.js 환경에서만 동적 로드 시도
|
|
213
|
+
if (typeof process !== 'undefined' && process.cwd && typeof require !== 'undefined') {
|
|
214
|
+
try {
|
|
215
|
+
const fs = require('fs');
|
|
216
|
+
const path = require('path');
|
|
217
|
+
const projectRoot = process.cwd();
|
|
218
|
+
// 설정 파일 경로 후보
|
|
219
|
+
const configPaths = [
|
|
220
|
+
path.join(projectRoot, 'hua-ux.config.ts'),
|
|
221
|
+
path.join(projectRoot, 'hua-ux.config.js'),
|
|
222
|
+
path.join(projectRoot, 'hua-ux.config.mjs'),
|
|
223
|
+
];
|
|
224
|
+
// 첫 번째로 발견된 설정 파일 사용
|
|
225
|
+
//
|
|
226
|
+
// ⚠️ 주의: 이 코드는 Fallback 용도입니다.
|
|
227
|
+
// 권장 방법: 설정 파일을 명시적으로 import하여 타입 안전성을 보장하세요.
|
|
228
|
+
//
|
|
229
|
+
// Next.js 빌드 시 동적 require는 경고를 발생시킬 수 있지만,
|
|
230
|
+
// 런타임에서는 정상 작동합니다. 설정 파일은 보통 빌드 타임에 처리되므로
|
|
231
|
+
// 이 코드는 주로 개발 환경에서 사용됩니다.
|
|
232
|
+
//
|
|
233
|
+
// 실제 프로덕션에서는 설정 파일을 명시적으로 import하는 것을 권장합니다:
|
|
234
|
+
// ```ts
|
|
235
|
+
// import config from './hua-ux.config';
|
|
236
|
+
// import { setConfig } from '@hua-labs/hua-ux/framework';
|
|
237
|
+
// setConfig(config);
|
|
238
|
+
// ```
|
|
239
|
+
for (const configPath of configPaths) {
|
|
240
|
+
if (fs.existsSync(configPath)) {
|
|
241
|
+
try {
|
|
242
|
+
// 동적 require는 Next.js 빌드 시 경고를 발생시킬 수 있지만
|
|
243
|
+
// 런타임에서는 정상 작동합니다.
|
|
244
|
+
// 실제 프로덕션에서는 설정 파일이 이미 import되어 있으므로
|
|
245
|
+
// 이 경로는 거의 사용되지 않습니다.
|
|
246
|
+
if (typeof require !== 'undefined' && typeof require.resolve === 'function') {
|
|
247
|
+
try {
|
|
248
|
+
// webpackIgnore 주석으로 Next.js 빌드 시 무시하도록 시도
|
|
249
|
+
// @ts-ignore - 동적 require는 타입 체크를 통과하지 못함
|
|
250
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
251
|
+
// ⚠️ Fallback 용도: 명시적 import를 권장합니다.
|
|
252
|
+
const configModule = require(/* webpackIgnore: true */ configPath);
|
|
253
|
+
const userConfig = configModule.default || configModule;
|
|
254
|
+
// Preset 병합 처리
|
|
255
|
+
if (userConfig && typeof userConfig === 'object') {
|
|
256
|
+
if (userConfig.preset) {
|
|
257
|
+
const { preset, ...rest } = userConfig;
|
|
258
|
+
cachedConfig = mergePresetWithConfig(preset, rest);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
cachedConfig = createConfigFromUserConfig(userConfig);
|
|
262
|
+
}
|
|
263
|
+
cachedConfig = validateConfig(cachedConfig);
|
|
264
|
+
return cachedConfig;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch (requireError) {
|
|
268
|
+
// require 실패 (TypeScript 파일 등)
|
|
269
|
+
// 기본값 사용
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (fileError) {
|
|
275
|
+
// 파일 읽기 실패
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
// fs, path 등이 없는 환경 (브라우저, Edge Runtime 등)
|
|
283
|
+
// 기본값 사용
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// 기본값 (product preset)
|
|
287
|
+
// 설정 파일이 없거나 로드 실패 시
|
|
288
|
+
cachedConfig = mergePresetWithConfig('product', {});
|
|
289
|
+
return cachedConfig;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Get current configuration
|
|
293
|
+
*
|
|
294
|
+
* 캐시된 설정을 반환하거나, 없으면 로드합니다.
|
|
295
|
+
*
|
|
296
|
+
* **클라이언트 안전**: 클라이언트에서는 항상 기본값을 반환합니다.
|
|
297
|
+
* **Client Safe**: Always returns default config on client side.
|
|
298
|
+
*/
|
|
299
|
+
export function getConfig() {
|
|
300
|
+
// 캐시된 설정이 있으면 반환
|
|
301
|
+
if (cachedConfig) {
|
|
302
|
+
return cachedConfig;
|
|
303
|
+
}
|
|
304
|
+
// 클라이언트 환경에서는 loadConfig를 호출하지 않고 기본값 반환
|
|
305
|
+
// (loadConfig는 서버 전용이며 fs 모듈을 사용함)
|
|
306
|
+
// 단, setConfig로 설정된 경우는 캐시를 우선 사용
|
|
307
|
+
if (typeof window !== 'undefined') {
|
|
308
|
+
cachedConfig = mergePresetWithConfig('product', {});
|
|
309
|
+
return cachedConfig;
|
|
310
|
+
}
|
|
311
|
+
// 서버 환경에서만 loadConfig 호출
|
|
312
|
+
return loadConfig();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Set configuration (for testing or manual override)
|
|
316
|
+
*
|
|
317
|
+
* 테스트나 수동 오버라이드를 위한 설정 설정 함수
|
|
318
|
+
*/
|
|
319
|
+
export function setConfig(config) {
|
|
320
|
+
cachedConfig = validateConfig(config);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Reset configuration cache
|
|
324
|
+
*
|
|
325
|
+
* 설정 캐시를 초기화합니다. (주로 테스트용)
|
|
326
|
+
*/
|
|
327
|
+
export function resetConfig() {
|
|
328
|
+
cachedConfig = null;
|
|
329
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Config Merge
|
|
3
|
+
*
|
|
4
|
+
* Preset 병합 및 깊은 병합 로직
|
|
5
|
+
*/
|
|
6
|
+
import type { HuaUxConfig, Preset } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Preset과 사용자 설정 병합
|
|
9
|
+
*
|
|
10
|
+
* 1. Preset 기본값 로드
|
|
11
|
+
* 2. Preset 설정 오버라이드 (개발자 모드인 경우)
|
|
12
|
+
* 3. 사용자 설정으로 병합 (사용자 설정 우선)
|
|
13
|
+
* 4. 최종 검증
|
|
14
|
+
*
|
|
15
|
+
* @param preset - 사용할 Preset (문자열 또는 객체)
|
|
16
|
+
* @param userConfig - 사용자 설정 (선택적)
|
|
17
|
+
* @returns 병합된 설정
|
|
18
|
+
*/
|
|
19
|
+
export declare function mergePresetWithConfig(preset: Preset, userConfig?: Partial<HuaUxConfig>): HuaUxConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Preset 없이 사용자 설정만으로 Config 생성
|
|
22
|
+
*
|
|
23
|
+
* Preset을 사용하지 않고 모든 설정을 직접 지정하는 경우
|
|
24
|
+
*/
|
|
25
|
+
export declare function createConfigFromUserConfig(userConfig: Partial<HuaUxConfig>): HuaUxConfig;
|
|
26
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/framework/config/merge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAA4B,MAAM,UAAU,CAAC;AAqE9E;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAChC,WAAW,CAiEb;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,GAC/B,WAAW,CAyBb"}
|