create-bubbles 0.1.9 → 0.1.10

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 (77) hide show
  1. package/dist/index.js +3 -2
  2. package/package.json +1 -1
  3. package/template-nextjs-vinext-eslint/.dockerignore +3 -0
  4. package/template-nextjs-vinext-eslint/.vscode/settings.json +53 -0
  5. package/template-nextjs-vinext-eslint/Dockerfile +21 -0
  6. package/template-nextjs-vinext-eslint/README.md +100 -0
  7. package/template-nextjs-vinext-eslint/commitlint.config.js +1 -0
  8. package/template-nextjs-vinext-eslint/docker-compose.yaml +22 -0
  9. package/template-nextjs-vinext-eslint/eslint.config.js +20 -0
  10. package/template-nextjs-vinext-eslint/lefthook.yml +11 -0
  11. package/template-nextjs-vinext-eslint/next.config.ts +8 -0
  12. package/template-nextjs-vinext-eslint/nginx.conf +14 -0
  13. package/template-nextjs-vinext-eslint/package.json +50 -0
  14. package/template-nextjs-vinext-eslint/pnpm-workspace.yaml +7 -0
  15. package/template-nextjs-vinext-eslint/public/file.svg +1 -0
  16. package/template-nextjs-vinext-eslint/public/globe.svg +1 -0
  17. package/template-nextjs-vinext-eslint/public/logo-white.svg +128 -0
  18. package/template-nextjs-vinext-eslint/public/next.svg +1 -0
  19. package/template-nextjs-vinext-eslint/public/vercel.svg +1 -0
  20. package/template-nextjs-vinext-eslint/public/window.svg +1 -0
  21. package/template-nextjs-vinext-eslint/src/app/_components/Header/header.module.css +0 -0
  22. package/template-nextjs-vinext-eslint/src/app/_components/Header/header.tsx +7 -0
  23. package/template-nextjs-vinext-eslint/src/app/_components/Main/index.tsx +13 -0
  24. package/template-nextjs-vinext-eslint/src/app/antd-provider.tsx +30 -0
  25. package/template-nextjs-vinext-eslint/src/app/icon.svg +26 -0
  26. package/template-nextjs-vinext-eslint/src/app/layout.tsx +71 -0
  27. package/template-nextjs-vinext-eslint/src/app/page.module.css +141 -0
  28. package/template-nextjs-vinext-eslint/src/app/page.tsx +43 -0
  29. package/template-nextjs-vinext-eslint/src/assets/icon/logo-white.svg +128 -0
  30. package/template-nextjs-vinext-eslint/src/assets/icon/logo.svg +26 -0
  31. package/template-nextjs-vinext-eslint/src/assets/image/QR.png +0 -0
  32. package/template-nextjs-vinext-eslint/src/assets/image/banner_1.png +0 -0
  33. package/template-nextjs-vinext-eslint/src/assets/image/banner_2.png +0 -0
  34. package/template-nextjs-vinext-eslint/src/assets/image/banner_3.png +0 -0
  35. package/template-nextjs-vinext-eslint/src/assets/image/banner_4.png +0 -0
  36. package/template-nextjs-vinext-eslint/src/assets/image/banner_top.png +0 -0
  37. package/template-nextjs-vinext-eslint/src/assets/image/icon_title_left.png +0 -0
  38. package/template-nextjs-vinext-eslint/src/assets/image/icon_title_right.png +0 -0
  39. package/template-nextjs-vinext-eslint/src/assets/image/img.png +0 -0
  40. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_COCT.png +0 -0
  41. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/207/347/247/221.png +0 -0
  42. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/205/264.png +0 -0
  43. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/206/266/345/273/272/345/267/245.png +0 -0
  44. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/344/270/255/351/223/201.png +0 -0
  45. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/344/272/224/345/206/266.png +0 -0
  46. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/344/272/244/351/200/232/345/273/272/350/256/276.png +0 -0
  47. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/345/273/272/344/270/232.png +0 -0
  48. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/345/273/272/347/255/221/347/247/221/345/255/246/351/231/242.png +0 -0
  49. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/347/224/265/345/273/272.png +0 -0
  50. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/344/270/255/345/233/275/351/223/201/345/273/272.png +0 -0
  51. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/345/256/234/351/200/232/344/270/226/347/272/252.png +0 -0
  52. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/346/225/260/347/273/264/347/251/272/351/227/264.png +0 -0
  53. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/346/226/260/346/230/212/350/276/260/345/273/272/350/256/276.png +0 -0
  54. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/346/236/227/345/220/214/346/243/252/345/233/275/351/231/205.png +0 -0
  55. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/346/270/235/351/232/206/351/233/206/345/233/242.png +0 -0
  56. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/347/273/264/345/241/224/347/247/221/346/212/200.png +0 -0
  57. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/350/205/276/350/256/257.png +0 -0
  58. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/350/265/233/350/277/252/344/277/241/346/201/257.png +0 -0
  59. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/344/272/244/351/200/232/345/244/247/345/255/246.png +0 -0
  60. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/344/272/244/351/200/232/350/201/214/344/270/232/345/255/246/351/231/242.png +0 -0
  61. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/345/244/247/345/255/246.png +0 -0
  62. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/345/267/245/345/225/206/350/201/214/344/270/232/345/255/246/351/231/242.png +0 -0
  63. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/345/267/245/347/250/213/350/201/214/344/270/232/346/212/200/346/234/257/345/255/246/351/231/242.png +0 -0
  64. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/207/215/345/272/206/345/273/272/345/267/245.png +0 -0
  65. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/230/277/351/207/214/344/272/221.png +0 -0
  66. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/231/206/345/206/233/345/206/233/345/214/273/345/244/247/345/255/246.png +0 -0
  67. package/template-nextjs-vinext-eslint/src/assets/image/parteners/logo_/351/276/231/346/271/226.png +0 -0
  68. package/template-nextjs-vinext-eslint/src/styles/globals.css +47 -0
  69. package/template-nextjs-vinext-eslint/src/types/vite-env.d.ts +18 -0
  70. package/template-nextjs-vinext-eslint/src/utils/env.ts +14 -0
  71. package/template-nextjs-vinext-eslint/src/utils/index.ts +0 -0
  72. package/template-nextjs-vinext-eslint/src/utils/request/core/index.ts +182 -0
  73. package/template-nextjs-vinext-eslint/src/utils/request/core/utils.ts +30 -0
  74. package/template-nextjs-vinext-eslint/src/utils/request/index.ts +48 -0
  75. package/template-nextjs-vinext-eslint/tsconfig.json +34 -0
  76. package/template-nextjs-vinext-eslint/uno.config.ts +10 -0
  77. package/template-nextjs-vinext-eslint/vite.config.ts +8 -0
@@ -0,0 +1,47 @@
1
+ :root {
2
+ --background: #ffffff;
3
+ --foreground: #171717;
4
+
5
+ /* Brand tokens */
6
+ --brand-blue: #146ae1;
7
+ --brand-blue-dark: #0f52b0;
8
+ --brand-amber: #fdc23a;
9
+ --brand-text: #1a1a2e;
10
+ --brand-text-secondary: #555;
11
+ --brand-bg-light: #f5f8ff;
12
+ --brand-border: #e0e8f5;
13
+ }
14
+
15
+ html {
16
+ scroll-behavior: smooth;
17
+ }
18
+
19
+ body {
20
+ max-width: 100vw;
21
+ overflow-x: hidden;
22
+ }
23
+
24
+ body {
25
+ color: var(--foreground);
26
+ background: var(--background);
27
+ font-family: Arial, Helvetica, sans-serif;
28
+ -webkit-font-smoothing: antialiased;
29
+ -moz-osx-font-smoothing: grayscale;
30
+ }
31
+
32
+ * {
33
+ box-sizing: border-box;
34
+ padding: 0;
35
+ margin: 0;
36
+ }
37
+
38
+ a {
39
+ color: inherit;
40
+ text-decoration: none;
41
+ }
42
+
43
+ @media (prefers-color-scheme: dark) {
44
+ html {
45
+ color-scheme: dark;
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.svg?react' {
4
+ import type { FC, SVGProps } from 'react'
5
+
6
+ const ReactComponent: FC<SVGProps<SVGSVGElement>>
7
+ export default ReactComponent
8
+ }
9
+
10
+ declare module '*.svg' {
11
+ const src: string
12
+ export default src
13
+ }
14
+
15
+ declare module '*/png' {
16
+ const src: string
17
+ export default src
18
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 环境变量工具
3
+ * 所有环境变量通过 import.meta.env 读取,在此统一导出。
4
+ * 在 .env.local / .env.production 中配置对应变量。
5
+ */
6
+
7
+ /** API 基础域名,例如 https://api.example.com */
8
+ export const apiUrl: string = import.meta.env.VITE_API_URL ?? ''
9
+
10
+ /** 普通接口路径前缀,例如 api */
11
+ export const apiAffix: string = import.meta.env.VITE_API_AFFIX ?? 'api'
12
+
13
+ /** 上传接口路径前缀,例如 upload */
14
+ export const uploadApiAffix: string = import.meta.env.VITE_UPLOAD_API_AFFIX ?? 'upload'
@@ -0,0 +1,182 @@
1
+ import type {
2
+ AlovaGlobalCacheAdapter,
3
+ AlovaOptions,
4
+ AlovaRequestAdapter,
5
+ GlobalCacheConfig,
6
+ StatesExport,
7
+ StatesHook,
8
+ } from 'alova'
9
+ import type { FetchRequestInit } from 'alova/fetch'
10
+ import { createAlova } from 'alova'
11
+ import adapterFetch from 'alova/fetch'
12
+ import { deepMergeObject, isReadableStream } from './utils'
13
+
14
+ // ---- 支持的适配器联合类型 ----
15
+ type SupportedRequestConfig = FetchRequestInit
16
+ type SupportedResponse = Response
17
+ type SupportedResponseHeader = Headers
18
+
19
+ interface StatusMap {
20
+ success?: number
21
+ unAuthorized?: number
22
+ }
23
+
24
+ interface CodeMap {
25
+ success?: number[]
26
+ unAuthorized?: number[]
27
+ }
28
+
29
+ export interface BaseRequestOption<
30
+ RC extends SupportedRequestConfig = SupportedRequestConfig,
31
+ RE extends SupportedResponse = SupportedResponse,
32
+ RH extends SupportedResponseHeader = SupportedResponseHeader,
33
+ SE extends StatesExport<any> = StatesExport<any>,
34
+ > {
35
+ baseUrl?: string
36
+ timeout?: number
37
+ commonHeaders?: Record<string, string | (() => string)>
38
+ statusMap?: StatusMap
39
+ isWrapped?: boolean
40
+ cacheFor?: GlobalCacheConfig<any>
41
+ cacheLogger?: boolean
42
+ codeMap?: CodeMap
43
+ responseDataKey?: string
44
+ responseMessageKey?: string
45
+ isTransformResponse?: boolean
46
+ isShowSuccessMessage?: boolean
47
+ successDefaultMessage?: string
48
+ isShowErrorMessage?: boolean
49
+ errorDefaultMessage?: string
50
+ statesHook?: StatesHook<SE>
51
+ successMessageFunc?: (message: string) => void
52
+ errorMessageFunc?: (message: string) => void
53
+ unAuthorizedResponseFunc?: () => void
54
+ requestAdapter?: AlovaRequestAdapter<RC, RE, RH>
55
+ storageAdapter?: AlovaGlobalCacheAdapter
56
+ }
57
+
58
+ /** method.meta 中可按请求覆盖的字段 */
59
+ export interface RequestMeta {
60
+ isTransformResponse?: boolean
61
+ isShowSuccessMessage?: boolean
62
+ isShowErrorMessage?: boolean
63
+ }
64
+
65
+ function getMetaFlag(meta: Record<string, any> | undefined, key: string, fallback: boolean): boolean {
66
+ if (meta && typeof meta[key] === 'boolean')
67
+ return meta[key]
68
+ return fallback
69
+ }
70
+
71
+ export function createInstance<
72
+ RC extends SupportedRequestConfig = SupportedRequestConfig,
73
+ RE extends SupportedResponse = SupportedResponse,
74
+ RH extends SupportedResponseHeader = SupportedResponseHeader,
75
+ >(option: BaseRequestOption<RC, RE, RH>) {
76
+ const defaultOption: BaseRequestOption = {
77
+ baseUrl: '/',
78
+ timeout: undefined,
79
+ statusMap: { success: 200, unAuthorized: 401 },
80
+ isWrapped: true,
81
+ cacheFor: null,
82
+ cacheLogger: true,
83
+ codeMap: { success: [200], unAuthorized: [401] },
84
+ responseDataKey: 'data',
85
+ responseMessageKey: 'message',
86
+ isTransformResponse: true,
87
+ isShowSuccessMessage: false,
88
+ successDefaultMessage: '操作成功',
89
+ isShowErrorMessage: true,
90
+ errorDefaultMessage: '服务异常',
91
+ requestAdapter: adapterFetch() as AlovaRequestAdapter<any, any, any>,
92
+ }
93
+
94
+ const config = deepMergeObject(defaultOption as any, option as any) as Required<
95
+ Pick<BaseRequestOption, 'statusMap' | 'codeMap' | 'responseDataKey' | 'responseMessageKey'>
96
+ > & BaseRequestOption<RC, RE, RH>
97
+
98
+ const alovaOptions: AlovaOptions<{
99
+ Responded: any
100
+ Transformed: any
101
+ RequestConfig: RC
102
+ Response: RE
103
+ ResponseHeader: RH
104
+ L1Cache: AlovaGlobalCacheAdapter
105
+ L2Cache: AlovaGlobalCacheAdapter
106
+ StatesExport: StatesExport<any>
107
+ }> = {
108
+ baseURL: config.baseUrl,
109
+ timeout: config.timeout,
110
+ cacheFor: config.cacheFor as any,
111
+ cacheLogger: config.cacheLogger,
112
+ statesHook: config.statesHook,
113
+ l2Cache: config.storageAdapter,
114
+ requestAdapter: config.requestAdapter!,
115
+ beforeRequest: async (method) => {
116
+ for (const [key, value] of Object.entries(config.commonHeaders ?? {})) {
117
+ method.config.headers[key] = typeof value === 'function' ? value() : value
118
+ }
119
+ },
120
+ responded: {
121
+ onSuccess: async (response, method) => {
122
+ const meta = method.meta as Record<string, any> | undefined
123
+ const shouldTransform = getMetaFlag(meta, 'isTransformResponse', config.isTransformResponse ?? true)
124
+ const showSuccess = getMetaFlag(meta, 'isShowSuccessMessage', config.isShowSuccessMessage ?? false)
125
+ const showError = getMetaFlag(meta, 'isShowErrorMessage', config.isShowErrorMessage ?? true)
126
+ const isWrapped = getMetaFlag(meta, 'isWrapped', config.isWrapped ?? true)
127
+
128
+ if (!shouldTransform)
129
+ return response
130
+
131
+ // 兼容 fetch (status) 和 Taro (statusCode)
132
+ const status = (response as any).statusCode ?? (response as any).status
133
+ // 兼容 fetch (body 是 ReadableStream) 和 Taro (data 直接可用)
134
+ const data
135
+ = (response as any)?.body && isReadableStream((response as any).body)
136
+ ? await (response as Response).json()
137
+ : (response as any).data ?? response
138
+
139
+ if (status !== config.statusMap.success) {
140
+ if (config.statusMap.unAuthorized === status)
141
+ config.unAuthorizedResponseFunc?.()
142
+ if (showError)
143
+ config.errorMessageFunc?.(config.errorDefaultMessage ?? '服务异常')
144
+ return Promise.reject(response)
145
+ }
146
+
147
+ if (!isWrapped || (isWrapped === undefined || !config.isWrapped)) {
148
+ if (showSuccess)
149
+ config.successMessageFunc?.(config.successDefaultMessage ?? '操作成功')
150
+ return data
151
+ }
152
+
153
+ const code = data?.code
154
+ const responseData = data?.[config.responseDataKey]
155
+ const responseMessage = data?.[config.responseMessageKey]
156
+
157
+ if (!config.codeMap.success?.includes(+code)) {
158
+ if (config.codeMap.unAuthorized?.includes(+code)) {
159
+ config.unAuthorizedResponseFunc?.()
160
+ return Promise.reject(response)
161
+ }
162
+ if (showError)
163
+ config.errorMessageFunc?.(responseMessage ?? config.errorDefaultMessage ?? '服务异常')
164
+ return Promise.reject(response)
165
+ }
166
+
167
+ if (showSuccess)
168
+ config.successMessageFunc?.(responseMessage ?? config.successDefaultMessage)
169
+ return responseData
170
+ },
171
+ onError: (error, method) => {
172
+ const meta = method.meta as Record<string, any> | undefined
173
+ const showError = getMetaFlag(meta, 'isShowErrorMessage', config.isShowErrorMessage ?? true)
174
+ if (showError)
175
+ config.errorMessageFunc?.(config.errorDefaultMessage ?? error.message)
176
+ return Promise.reject(error)
177
+ },
178
+ },
179
+ }
180
+
181
+ return createAlova(alovaOptions)
182
+ }
@@ -0,0 +1,30 @@
1
+ export function deepMergeObject<T = any>(source: T, target: Partial<T>): T {
2
+ const isObject = (obj: any): obj is Record<string, any> =>
3
+ obj && typeof obj === 'object' && !Array.isArray(obj)
4
+
5
+ const merge = (src: any, tgt: any): any => {
6
+ const result = { ...src }
7
+ if (isObject(result) && isObject(tgt)) {
8
+ Object.keys(tgt).forEach((key) => {
9
+ if (isObject(tgt[key])) {
10
+ result[key] = merge(result[key] || {}, tgt[key])
11
+ }
12
+ else {
13
+ result[key] = tgt[key]
14
+ }
15
+ })
16
+ }
17
+ return result
18
+ }
19
+
20
+ return merge(source, target)
21
+ }
22
+
23
+ /**
24
+ * 判断一个变量是不是可读流
25
+ */
26
+ export function isReadableStream(data: unknown): boolean {
27
+ if (typeof ReadableStream === 'undefined')
28
+ return false
29
+ return data instanceof ReadableStream
30
+ }
@@ -0,0 +1,48 @@
1
+ import type { FetchRequestInit } from 'alova/fetch'
2
+ import { message } from 'antd'
3
+ import { apiAffix, apiUrl, uploadApiAffix } from '@/utils/env'
4
+ import { createInstance } from './core'
5
+
6
+ export const moduleUrl = {
7
+ LJSD: 'bee/single-track',
8
+ }
9
+
10
+ const alovaRequest = createInstance<FetchRequestInit, Response, Headers>({
11
+ baseUrl: `${apiUrl}/${apiAffix}`,
12
+ statusMap: { success: 200, unAuthorized: 401 },
13
+ codeMap: { success: [200] },
14
+ responseDataKey: 'data',
15
+ responseMessageKey: 'msg',
16
+ commonHeaders: {},
17
+ successMessageFunc: (msg) => {
18
+ message.success(msg)
19
+ },
20
+ errorMessageFunc: (msg) => {
21
+ message.error(msg)
22
+ },
23
+ unAuthorizedResponseFunc: () => {
24
+ message.warning('登录过期或未登录')
25
+ window.location.href = '/login'
26
+ },
27
+ })
28
+
29
+ export default alovaRequest
30
+
31
+ export const alovaUploadRequest = createInstance<FetchRequestInit, Response, Headers>({
32
+ baseUrl: `${apiUrl}/${uploadApiAffix}`,
33
+ statusMap: { success: 200, unAuthorized: 401 },
34
+ codeMap: { success: [200] },
35
+ responseDataKey: 'data',
36
+ responseMessageKey: 'msg',
37
+ commonHeaders: {},
38
+ successMessageFunc: (msg) => {
39
+ message.success(msg)
40
+ },
41
+ errorMessageFunc: (msg) => {
42
+ message.error(msg)
43
+ },
44
+ unAuthorizedResponseFunc: () => {
45
+ message.warning('登录过期或未登录')
46
+ window.location.href = '/login'
47
+ },
48
+ })
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "incremental": true,
4
+ "target": "ES2017",
5
+ "jsx": "react-jsx",
6
+ "lib": ["dom", "dom.iterable", "esnext"],
7
+ "module": "esnext",
8
+ "moduleResolution": "bundler",
9
+ "paths": {
10
+ "@/*": ["./src/*"]
11
+ },
12
+ "resolveJsonModule": true,
13
+ "allowJs": true,
14
+ "strict": true,
15
+ "noEmit": true,
16
+ "esModuleInterop": true,
17
+ "isolatedModules": true,
18
+ "skipLibCheck": true,
19
+ "plugins": [
20
+ {
21
+ "name": "next"
22
+ }
23
+ ]
24
+ },
25
+ "include": [
26
+ ".next/types/**/*.ts",
27
+ ".next/dev/types/**/*.ts",
28
+ "./src/types/vite-env.d.ts",
29
+ "**/*.ts",
30
+ "**/*.tsx",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }
@@ -0,0 +1,10 @@
1
+ import {
2
+ defineConfig,
3
+ presetAttributify,
4
+ presetIcons,
5
+ presetWind4,
6
+ } from 'unocss'
7
+
8
+ export default defineConfig({
9
+ presets: [presetWind4(), presetAttributify(), presetIcons()],
10
+ })
@@ -0,0 +1,8 @@
1
+ import UnoCSS from 'unocss/vite'
2
+ import vinext from 'vinext'
3
+ import { defineConfig } from 'vite'
4
+ import svgr from 'vite-plugin-svgr'
5
+
6
+ export default defineConfig({
7
+ plugins: [UnoCSS(), svgr(), vinext()],
8
+ })