@funhub/platform 0.1.51 → 0.1.52

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.
Files changed (65) hide show
  1. package/README.md +13 -0
  2. package/bin/index.mjs +323 -0
  3. package/dist/components/biz/business/banner/variants/basic-banner/material.d.mts +1 -1
  4. package/dist/components/biz/business/banner-carousel/material.d.mts +1 -1
  5. package/dist/components/biz/business/channel-list/material.d.mts +1 -1
  6. package/dist/components/biz/business/detail/materials/registry.d.mts +6 -6
  7. package/dist/components/biz/business/detail/materials/video-detail-actions/material.d.mts +1 -1
  8. package/dist/components/biz/business/detail/materials/video-detail-info/material.d.mts +1 -1
  9. package/dist/components/biz/business/detail/materials/video-detail-info-title/material.d.mts +1 -1
  10. package/dist/components/biz/business/detail/materials/video-detail-info-title-tags-episodes/material.d.mts +1 -1
  11. package/dist/components/biz/business/detail/materials/video-detail-player/material.d.mts +1 -1
  12. package/dist/components/biz/business/detail/materials/video-detail-recommend/material.d.mts +1 -1
  13. package/dist/components/biz/business/floating-ball/material.d.mts +1 -1
  14. package/dist/components/biz/business/header-search/header-avatar-icon/material.d.mts +1 -1
  15. package/dist/components/biz/business/header-search/header-avatar-logo-search/material.d.mts +1 -1
  16. package/dist/components/biz/business/header-search/header-avatar-logo-search-icon/material.d.mts +1 -1
  17. package/dist/components/biz/business/header-search/header-logo-search/material.d.mts +1 -1
  18. package/dist/components/biz/business/header-search/header-search/material.d.mts +1 -1
  19. package/dist/components/biz/business/home-recommend/variants/home-recommend-grid/material.d.mts +1 -1
  20. package/dist/components/biz/business/home-recommend/variants/home-recommend-waterfall/material.d.mts +1 -1
  21. package/dist/components/biz/business/large-feature-grid/material.d.mts +2 -2
  22. package/dist/components/biz/business/marquee/material.d.mts +1 -1
  23. package/dist/components/biz/business/profile/profile-header/material.d.mts +2 -2
  24. package/dist/components/biz/business/profile/profile-main/material.d.mts +1 -1
  25. package/dist/components/biz/business/search-history/material.d.mts +1 -1
  26. package/dist/components/biz/business/search-input/material.d.mts +1 -1
  27. package/dist/components/biz/business/shortcut-grid/material.d.mts +1 -1
  28. package/dist/components/biz/business/tab-bar/material.d.mts +1 -1
  29. package/dist/components/biz/business/text-recommend/material.d.mts +1 -1
  30. package/dist/components/biz/business/video-horizontal-list/material.d.mts +1 -1
  31. package/dist/components/biz/example/button/material.d.mts +1 -1
  32. package/dist/components/biz/example/button/material.mjs +1 -1
  33. package/dist/components/pages/login/password.mjs +1 -1
  34. package/dist/components/pages/login/reset-password.mjs +1 -1
  35. package/dist/components/pages/login/verify.mjs +1 -1
  36. package/dist/components/pages/settings/_components/reset-password-drawer.mjs +1 -1
  37. package/dist/components/pages/settings/_components/settings.mjs +1 -1
  38. package/dist/components/ui/image.d.mts +4 -4
  39. package/dist/i18n/locales/en.mjs +1 -1
  40. package/dist/i18n/locales/zh-CN.mjs +1 -1
  41. package/dist/utils/password-validator.d.mts +28 -0
  42. package/dist/utils/password-validator.mjs +2 -0
  43. package/dist/utils/schema/index.d.mts +1 -1
  44. package/dist/utils/schema/material.d.mts +7 -9
  45. package/dist/utils/schema/utils.d.mts +13 -3
  46. package/dist/utils/schema/utils.mjs +1 -1
  47. package/dist/utils.d.mts +3 -2
  48. package/dist/utils.mjs +1 -1
  49. package/package.json +7 -2
  50. package/templates/base/_meta.json +4 -0
  51. package/templates/base/template/README.md.template +32 -0
  52. package/templates/base/template/__dot__gitignore +6 -0
  53. package/templates/base/template/app/[locale]/layout.tsx.template +36 -0
  54. package/templates/base/template/app/[locale]/page.tsx.template +24 -0
  55. package/templates/base/template/app/globals.css +26 -0
  56. package/templates/base/template/app/layout.tsx.template +38 -0
  57. package/templates/base/template/eslint.config.mjs.template +68 -0
  58. package/templates/base/template/i18n/request.ts.template +3 -0
  59. package/templates/base/template/next-env.d.ts.template +4 -0
  60. package/templates/base/template/next.config.ts.template +21 -0
  61. package/templates/base/template/package.json.template +37 -0
  62. package/templates/base/template/postcss.config.js.template +18 -0
  63. package/templates/base/template/proxy.ts.template +18 -0
  64. package/templates/base/template/tailwind.config.cjs.template +13 -0
  65. package/templates/base/template/tsconfig.json.template +43 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@funhub/platform",
3
3
  "type": "module",
4
- "version": "0.1.51",
4
+ "version": "0.1.52",
5
5
  "private": false,
6
6
  "sideEffects": [
7
7
  "**/*.css"
@@ -62,9 +62,12 @@
62
62
  },
63
63
  "./theme.css": "./theme.css"
64
64
  },
65
+ "bin": "./bin/index.mjs",
65
66
  "files": [
67
+ "bin",
66
68
  "config",
67
69
  "dist",
70
+ "templates",
68
71
  "theme.css"
69
72
  ],
70
73
  "scripts": {
@@ -89,7 +92,8 @@
89
92
  "i18n:build": "node scripts/i18n-flat-sync.mjs build",
90
93
  "i18n:watch": "node scripts/i18n-flat-sync.mjs watch",
91
94
  "i18n:check": "node scripts/i18n-flat-sync.mjs check",
92
- "pretest": "pnpm i18n:build"
95
+ "pretest": "pnpm i18n:build",
96
+ "init:local": "node ./bin/index.mjs"
93
97
  },
94
98
  "peerDependencies": {
95
99
  "@tanstack/query-core": ">=5",
@@ -107,6 +111,7 @@
107
111
  "@ncdai/react-wheel-picker": "^1.1.0",
108
112
  "@next/bundle-analyzer": "^16.1.6",
109
113
  "browser-image-compression": "^2.0.2",
114
+ "cac": "^6.7.14",
110
115
  "class-variance-authority": "^0.7.1",
111
116
  "clsx": "^2.1.1",
112
117
  "crypto": "^1.0.1",
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "base",
3
+ "description": "最小可运行的 Funhub Next.js starter"
4
+ }
@@ -0,0 +1,32 @@
1
+ # {{PROJECT_NAME}}
2
+
3
+ 基于 `@funhub/platform` 初始化的 Next.js Starter。
4
+
5
+ ## 开始使用
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm dev
10
+ ```
11
+
12
+ ## 可用命令
13
+
14
+ ```bash
15
+ pnpm dev
16
+ pnpm build
17
+ pnpm start
18
+ pnpm lint
19
+ pnpm typecheck
20
+ ```
21
+
22
+ ## 目录说明
23
+
24
+ - `app/`: Next App Router 路由
25
+ - `i18n/`: next-intl 请求配置
26
+ - `proxy.ts`: 国际化路由中间件
27
+
28
+ ## 依赖说明
29
+
30
+ - `@funhub/platform`: SDK 主包
31
+ - `@funhub/platform/config/tailwind`: Tailwind 预设与内容扫描配置
32
+ - `@funhub/platform/theme.css`: 平台主题变量
@@ -0,0 +1,6 @@
1
+ .next
2
+ node_modules
3
+ dist
4
+ coverage
5
+ *.log
6
+ .DS_Store
@@ -0,0 +1,36 @@
1
+ import type { ReactNode } from 'react';
2
+ import { FunhubProvider, LocaleSync } from '@funhub/platform/components/common';
3
+ import { defaultLocale, getMessages, isValidLocale, locales } from '@funhub/platform/i18n';
4
+ import { setRequestLocale } from 'next-intl/server';
5
+
6
+ interface LocaleLayoutProps {
7
+ children: ReactNode
8
+ params: Promise<{ locale: string }>
9
+ }
10
+
11
+ /**
12
+ * 预生成支持的语言参数。
13
+ */
14
+ export function generateStaticParams() {
15
+ return locales.map(item => ({ locale: item.code }));
16
+ }
17
+
18
+ /**
19
+ * 语言布局负责注入平台 Provider 与国际化上下文。
20
+ */
21
+ export default async function LocaleLayout({ children, params }: LocaleLayoutProps) {
22
+ const { locale } = await params;
23
+ const validLocale = isValidLocale(locale) ? locale : defaultLocale;
24
+
25
+ setRequestLocale(validLocale);
26
+ const messages = getMessages(validLocale);
27
+
28
+ return (
29
+ <>
30
+ <LocaleSync locale={validLocale} />
31
+ <FunhubProvider intl={{ locale: validLocale, messages }}>
32
+ {children}
33
+ </FunhubProvider>
34
+ </>
35
+ );
36
+ }
@@ -0,0 +1,24 @@
1
+ import { Button } from '@funhub/platform/components/biz';
2
+ import { DebugLocaleSwitcher } from '@funhub/platform/components/common';
3
+
4
+ /**
5
+ * Starter 首页,展示平台组件已接入成功。
6
+ */
7
+ export default function HomePage() {
8
+ return (
9
+ <main className='min-h-screen bg-bg1 px-6 py-10 text-text1'>
10
+ <section className='mx-auto flex max-w-xl flex-col gap-4 rounded-3xl bg-bg2 p-6 shadow-sm'>
11
+ <span className='text-sm text-text3'>@funhub/platform starter</span>
12
+ <h1 className='text-2xl font-semibold'>{'{{PROJECT_NAME}}'}</h1>
13
+ <p className='text-sm leading-6 text-text2'>
14
+ 这个项目已经接入平台主题、Tailwind 预设、next-intl 和 FunhubProvider,
15
+ 你可以直接开始组合页面组件、业务组件或物料渲染能力。
16
+ </p>
17
+ <div className='flex flex-wrap gap-3 pt-2'>
18
+ <Button text='平台按钮已就绪' variant='red' disabled={false} />
19
+ <DebugLocaleSwitcher />
20
+ </div>
21
+ </section>
22
+ </main>
23
+ );
24
+ }
@@ -0,0 +1,26 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ html {
6
+ font-size: 16px;
7
+ }
8
+
9
+ body {
10
+ font-family: var(--font-sans), Arial, Helvetica, sans-serif;
11
+ -webkit-text-size-adjust: 100%;
12
+ -moz-text-size-adjust: 100%;
13
+ -ms-text-size-adjust: 100%;
14
+ text-size-adjust: 100%;
15
+ background: var(--color-bg1);
16
+ color: var(--color-text1);
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ a {
24
+ color: inherit;
25
+ text-decoration: none;
26
+ }
@@ -0,0 +1,38 @@
1
+ import type { Metadata, Viewport } from 'next';
2
+ import { ThemeSync } from '@funhub/platform/components/common';
3
+ import { defaultLocale } from '@funhub/platform/i18n';
4
+ import '@funhub/platform/theme.css';
5
+ import './globals.css';
6
+
7
+ /**
8
+ * Starter 应用默认 viewport 配置。
9
+ */
10
+ export const viewport: Viewport = {
11
+ width: 'device-width',
12
+ initialScale: 1,
13
+ viewportFit: 'cover',
14
+ };
15
+
16
+ /**
17
+ * Starter 应用的站点元信息。
18
+ */
19
+ export const metadata: Metadata = {
20
+ title: '{{PROJECT_NAME}}',
21
+ description: 'A starter app powered by @funhub/platform',
22
+ };
23
+
24
+ /**
25
+ * 根布局负责挂载主题和全局样式。
26
+ */
27
+ export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
28
+ const theme = 'dark';
29
+
30
+ return (
31
+ <html lang={defaultLocale} className={theme} data-prefers-color-scheme={theme}>
32
+ <body suppressHydrationWarning>
33
+ <ThemeSync defaultTheme={theme} />
34
+ {children}
35
+ </body>
36
+ </html>
37
+ );
38
+ }
@@ -0,0 +1,68 @@
1
+ import { antfu } from '@antfu/eslint-config';
2
+
3
+ export function react(options = {}) {
4
+ return antfu({
5
+ react: true,
6
+ ignores: [
7
+ '**/*.md',
8
+ '.next/**',
9
+ 'out/**',
10
+ 'build/**',
11
+ 'public',
12
+ 'next-env.d.ts',
13
+ ...(options.ignores || []),
14
+ ],
15
+ rules: {
16
+ 'react-hooks/exhaustive-deps': 'error',
17
+ 'eslint-comments/no-unlimited-disable': 'off',
18
+ 'no-redeclare': 'off',
19
+ 'jsdoc/require-returns-description': 'off',
20
+ '@typescript-eslint/no-redeclare': 'off',
21
+ 'style/quotes': ['warn', 'single'],
22
+ 'style/jsx-quotes': ['warn', 'prefer-single'],
23
+ 'node/prefer-global/process': 'off',
24
+ 'style/semi': ['warn', 'always'],
25
+ 'package-json/valid-package-def': 'off',
26
+ '@eslint-react/no-missing-key': 'warn',
27
+ 'no-restricted-syntax': 'off',
28
+ 'react-hooks-extra/no-direct-set-state-in-use-effect': 'off',
29
+ 'import/no-anonymous-default-export': 'off',
30
+ 'eqeqeq': 'warn',
31
+ 'ts/no-use-before-define': ['warn', { functions: false, variables: false }],
32
+ 'no-use-before-define': ['warn', { functions: false, variables: false }],
33
+ 'no-console': 'warn',
34
+ 'unicorn/prefer-math-trunc': 'off',
35
+ 'unicorn/prefer-dom-node-remove': 'off',
36
+ '@typescript-eslint/no-unsafe-function-type': 'off',
37
+ 'no-empty': 'off',
38
+ '@typescript-eslint/no-empty-object-type': 'warn',
39
+ 'unicorn/prefer-query-selector': 0,
40
+ 'regexp/no-super-linear-backtracking': 0,
41
+ 'regexp/no-useless-assertions': 0,
42
+ 'unicorn/no-new-array': 0,
43
+ '@typescript-eslint/method-signature-style': 0,
44
+ 'unicorn/prefer-code-point': 'warn',
45
+ 'unicorn/no-object-as-default-parameter': 'warn',
46
+ 'unused-imports/no-unused-vars': 'warn',
47
+ '@eslint-react/no-unstable-default-props': 'warn',
48
+ 'unicorn/prefer-regexp-test': 'warn',
49
+ 'no-unsafe-optional-chaining': 'warn',
50
+ 'unicorn/prefer-logical-operator-over-ternary': 'warn',
51
+ 'arrow-body-style': 0,
52
+ 'unicorn/no-array-callback-reference': 0,
53
+ 'prefer-regex-literals': 0,
54
+ 'regexp/optimal-quantifier-concatenation': 'warn',
55
+ 'unicorn/prefer-string-slice': 0,
56
+ 'array-callback-return': 0,
57
+ 'regexp/no-unused-capturing-group': 1,
58
+ 'unicorn/no-anonymous-default-export': 0,
59
+ 'unicorn/no-magic-array-flat-depth': 1,
60
+ 'react-refresh/only-export-components': 0,
61
+ 'react/no-array-index-key': 0,
62
+ 'package-json/valid-name': 0,
63
+ ...(options.rules || {}),
64
+ },
65
+ });
66
+ }
67
+
68
+ export default react();
@@ -0,0 +1,3 @@
1
+ import { nextIntlRequestConfig } from '@funhub/platform/i18n';
2
+
3
+ export default nextIntlRequestConfig;
@@ -0,0 +1,4 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // This file is auto-generated by Next.js.
@@ -0,0 +1,21 @@
1
+ import type { NextConfig } from 'next';
2
+ import createNextIntlPlugin from 'next-intl/plugin';
3
+
4
+ const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
5
+
6
+ /**
7
+ * Starter 应用的 Next 配置。
8
+ */
9
+ const nextConfig: NextConfig = {
10
+ transpilePackages: ['@funhub/platform'],
11
+ images: {
12
+ remotePatterns: [
13
+ {
14
+ protocol: 'https',
15
+ hostname: '*',
16
+ },
17
+ ],
18
+ },
19
+ };
20
+
21
+ export default withNextIntl(nextConfig);
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "{{PACKAGE_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint .",
10
+ "fix": "eslint . --fix",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@funhub/platform": "{{PLATFORM_VERSION}}",
15
+ "@tanstack/react-query": "^5.90.16",
16
+ "next": "16.1.6",
17
+ "next-intl": "^4.8.2",
18
+ "react": "19.2.0",
19
+ "react-dom": "19.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@antfu/eslint-config": "^7.4.3",
23
+ "@eslint-react/eslint-plugin": "^2.12.4",
24
+ "@types/node": "^20.19.17",
25
+ "@types/react": "^19.2.2",
26
+ "@types/react-dom": "^19.2.2",
27
+ "autoprefixer": "^10.4.23",
28
+ "eslint": "^10.0.0",
29
+ "eslint-plugin-react-hooks": "^7.0.1",
30
+ "eslint-plugin-react-refresh": "^0.5.0",
31
+ "postcss": "^8.5.6",
32
+ "postcss-nesting": "^13.0.2",
33
+ "postcss-px-to-viewport-8-plugin": "^1.2.5",
34
+ "tailwindcss": "^3.4.19",
35
+ "typescript": "^5.9.2"
36
+ }
37
+ }
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ plugins: {
3
+ 'postcss-nesting': {},
4
+ 'tailwindcss': {},
5
+ 'autoprefixer': {},
6
+ 'postcss-px-to-viewport-8-plugin': {
7
+ unitToConvert: 'px',
8
+ viewportUnit: 'vw',
9
+ unitPrecision: 6,
10
+ fontViewportUnit: 'vw',
11
+ selectorBlackList: [],
12
+ minPixelValue: 1,
13
+ mediaQuery: false,
14
+ replace: true,
15
+ viewportWidth: 430,
16
+ },
17
+ },
18
+ };
@@ -0,0 +1,18 @@
1
+ import type { NextRequest } from 'next/server';
2
+ import { routing } from '@funhub/platform/i18n';
3
+ import createMiddleware from 'next-intl/middleware';
4
+
5
+ const handleI18nRouting = createMiddleware(routing);
6
+
7
+ /**
8
+ * 处理 Starter 应用的国际化路由。
9
+ * @param {NextRequest} request
10
+ */
11
+ export default async function middleware(request: NextRequest) {
12
+ const response = handleI18nRouting(request);
13
+ return response;
14
+ }
15
+
16
+ export const config = {
17
+ matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
18
+ };
@@ -0,0 +1,13 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ const {
3
+ platformTailwindPreset,
4
+ withPlatformTailwindContent,
5
+ } = require('@funhub/platform/config/tailwind');
6
+
7
+ module.exports = {
8
+ content: withPlatformTailwindContent([
9
+ './app/**/*.{js,ts,jsx,tsx}',
10
+ './components/**/*.{js,ts,jsx,tsx}',
11
+ ]),
12
+ presets: [platformTailwindPreset],
13
+ };
@@ -0,0 +1,43 @@
1
+ {
2
+ "compilerOptions": {
3
+ "incremental": true,
4
+ "target": "ES2017",
5
+ "jsx": "react-jsx",
6
+ "lib": [
7
+ "dom",
8
+ "dom.iterable",
9
+ "esnext"
10
+ ],
11
+ "module": "esnext",
12
+ "moduleResolution": "bundler",
13
+ "paths": {
14
+ "@/*": [
15
+ "./*"
16
+ ]
17
+ },
18
+ "resolveJsonModule": true,
19
+ "allowJs": true,
20
+ "strict": true,
21
+ "noEmit": true,
22
+ "esModuleInterop": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+ "isolatedModules": true,
25
+ "skipLibCheck": true,
26
+ "plugins": [
27
+ {
28
+ "name": "next"
29
+ }
30
+ ]
31
+ },
32
+ "include": [
33
+ "next-env.d.ts",
34
+ "**/*.ts",
35
+ "**/*.tsx",
36
+ ".next/types/**/*.ts",
37
+ ".next/dev/types/**/*.ts",
38
+ "**/*.mts"
39
+ ],
40
+ "exclude": [
41
+ "node_modules"
42
+ ]
43
+ }