create-young-proj 1.3.0 → 1.5.0

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.
@@ -0,0 +1,204 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-11-10 18:02:07
4
+ * @LastEditTime: 2023-11-27 15:01:31
5
+ * @Description:
6
+ */
7
+ import { resolve } from 'node:path'
8
+ import { loadConfig } from 'c12'
9
+ import md5 from 'md5'
10
+
11
+ /**
12
+ * 签名
13
+ * @param params 参与签名的参数
14
+ * @param token 秘钥
15
+ */
16
+ export function signFn(params: Record<string, any>, token: string) {
17
+ const asciiSortedIndexArr = Object.keys(params).sort()
18
+ let str = ''
19
+ const obj: Record<string, any> = {}
20
+ if (asciiSortedIndexArr.length > 0) {
21
+ for (const key of asciiSortedIndexArr) {
22
+ const v = params[key]
23
+ if (v !== null && v !== '') {
24
+ str += `${key}=${encodeURIComponent(v)}&`
25
+ obj[key] = v
26
+ }
27
+ }
28
+ }
29
+ str += `token=${token}`
30
+ return {
31
+ sign: md5(str).toUpperCase(),
32
+ rawValue: obj,
33
+ }
34
+ }
35
+
36
+ /**
37
+ * 服务上报
38
+ */
39
+ export async function useServerReport(port: number) {
40
+ enum ReportURL {
41
+ 上线 = '/register/login',
42
+ 心跳 = '/register/heart',
43
+ }
44
+
45
+ const commonReq = async <T>(url: string, data: Record<string, any>, token: string) => {
46
+ const api_server_url
47
+ = process.env.NUXT_PUBLIC_API_SERVER || `http://${process.env.APIGATEHOST}`
48
+ const { sign, rawValue } = signFn(data, token)
49
+
50
+ console.log('🚀 ~ file: env.ts:41 ~ commonReq ~ api_server_url:', api_server_url, rawValue)
51
+
52
+ const headers = {
53
+ 'Authorization': `Bearer ${token}`,
54
+ 'content-type': 'application/json; charset=utf-8;',
55
+ 'time': `${Math.floor(Date.now() / 1000)}`,
56
+ sign,
57
+ }
58
+
59
+ return $fetch<T>(`${api_server_url}${url}`, {
60
+ method: 'post',
61
+ headers,
62
+ body: JSON.stringify(rawValue),
63
+ })
64
+ }
65
+
66
+ /**
67
+ * auth token
68
+ */
69
+ let token: string
70
+
71
+ /**
72
+ * 登录/获取 token
73
+ */
74
+ const login = async () => {
75
+ const data = {
76
+ serverId: process.env.APP_SERVER_ID,
77
+ serverName: process.env.APP_SERVER_NAME,
78
+ }
79
+
80
+ const { data: _data } = await commonReq<{
81
+ code: number
82
+ message: string
83
+ data: { token: string }
84
+ }>('/account/v1/internal/service/get_token', data, process.env.APP_SERVER_SECERET as string)
85
+
86
+ console.log('🚀 ~ file: env.ts:73 ~ login ~ _data:', _data)
87
+
88
+ const { token } = _data
89
+ console.log('login success, token: ', token, '\ntime: ', new Date().toLocaleString())
90
+ return token
91
+ }
92
+
93
+ /**
94
+ * 获取 auth token
95
+ */
96
+ const getToken = async () => {
97
+ if (!token) {
98
+ token = await login()
99
+ setInterval(() => {
100
+ // 每 23 小时刷一次 token
101
+ token = ''
102
+ }, 1000 * 3600 * 23)
103
+ }
104
+ return token
105
+ }
106
+
107
+ /**
108
+ * 服务上线
109
+ */
110
+ const report = async (url: ReportURL) => {
111
+ const token = await getToken()
112
+ try {
113
+ const res = await commonReq<{
114
+ host: string
115
+ port: string | number
116
+ weight: number
117
+ expire: number
118
+ }>(url, { port }, token)
119
+
120
+ console.log('请求成功:', url, new Date().toLocaleString())
121
+ return res
122
+ }
123
+ catch (error) {
124
+ console.error('请求失败:', url, error)
125
+ }
126
+ }
127
+
128
+ console.log('------------------------服务登录------------------------')
129
+ await login()
130
+ console.log('--------------------------------------------------------')
131
+
132
+ console.log('------------------------服务上线------------------------')
133
+ const info1 = await report(ReportURL.上线)
134
+ console.log('🚀 ~ file: init.ts:156 ~ defineNitroPlugin ~ info', info1)
135
+ console.log('--------------------------------------------------------')
136
+
137
+ console.log('------------------------服务心跳上报----------------------')
138
+ const info2 = await report(ReportURL.心跳)
139
+ console.log('🚀 ~ file: init.ts:163 ~ setInterval ~ info', info2)
140
+ console.log('----------------------------------------------------------')
141
+ setInterval(async () => {
142
+ console.log('------------------------服务心跳上报----------------------')
143
+ const info = await report(ReportURL.心跳)
144
+ console.log('🚀 ~ file: init.ts:163 ~ setInterval ~ info', info)
145
+ console.log('----------------------------------------------------------')
146
+ }, 1e4)
147
+ }
148
+
149
+ export default defineNitroPlugin(async (nitroApp) => {
150
+ const env = (process.env.DEPLOY_ENV as 'dev' | 'test' | 'online') || 'dev'
151
+ const { config } = await loadConfig<Record<string, any>>({
152
+ name: env,
153
+ cwd: resolve(process.cwd(), 'config'),
154
+ defaultConfig: {
155
+ // 此处可以放置通用的环境变量
156
+ // 由于频繁修改 package.json 会浪费 docker 性能,故将版本信息放于此处
157
+ // 优先读取环境变量中的版本信息(自己打的 Tag)
158
+ NUXT_PUBLIC_CURRENT_VERSION: process.env.PROJECT_VERSION || 'v0.0.1',
159
+
160
+ // 服务秘钥,不对前端开放
161
+ APP_SERVER_SECERET: '我是秘钥',
162
+ APP_SERVER_NAME: '我是服务名称',
163
+ APP_SERVER_ID: '我是服务id',
164
+ },
165
+ })
166
+
167
+ for (const key in config) {
168
+ if (process.env[key]) {
169
+ console.log(
170
+ '系统环境变量优先: ',
171
+ key,
172
+ ' = ',
173
+ process.env[key],
174
+ ' -> ',
175
+ config[key],
176
+ ' -> ',
177
+ '覆盖',
178
+ )
179
+ config[key] = process.env[key]
180
+ }
181
+ else {
182
+ process.env[key] = config[key]
183
+ }
184
+ if (!(key.indexOf('NUXT_PUBLIC_') === 0))
185
+ delete config[key]
186
+ }
187
+
188
+ console.log('------------------------读取配置文件------------------------')
189
+ console.log(config)
190
+ console.log('-------------------------------------------------------------')
191
+
192
+ nitroApp.hooks.hook('request', (event) => {
193
+ const headers = event.node.req.headers
194
+ const path = event.node.req.url
195
+ console.log('path', path, 'ua', headers['user-agent'], 'x-forwarded-for', headers['x-forwarded-for'], 'x-real-ip', headers['x-real-ip'])
196
+ })
197
+
198
+ // 本地开发,不上报
199
+ if (process.env.NODE_ENV === 'development')
200
+ return
201
+
202
+ const port = process.env.LISTEN_PORT || 3333
203
+ useServerReport(+port)
204
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./.nitro/types/tsconfig.json"
3
+ }
@@ -0,0 +1,66 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-11-08 16:35:24
4
+ * @LastEditTime: 2023-11-08 16:37:49
5
+ * @Description:
6
+ */
7
+ import fs from 'node:fs'
8
+ import type { Plugin } from 'vite'
9
+ import { defineConfig } from 'vite'
10
+ import Components from 'unplugin-vue-components/vite'
11
+ import Unocss from 'unocss/vite'
12
+ import { presetAttributify, presetIcons, presetUno } from 'unocss'
13
+ import { resolve } from 'pathe'
14
+
15
+ export default defineConfig({
16
+ optimizeDeps: {
17
+ // vitepress is aliased with replacement `join(DIST_CLIENT_PATH, '/index')`
18
+ // This needs to be excluded from optimization
19
+ exclude: ['@vueuse/core', 'vitepress'],
20
+ },
21
+ server: {
22
+ host: true,
23
+ hmr: {
24
+ overlay: false,
25
+ },
26
+ },
27
+ plugins: [
28
+ Components({
29
+ include: [/\.vue/, /\.md/],
30
+ dirs: '.vitepress/components',
31
+ dts: '.vitepress/components.d.ts',
32
+ }) as Plugin,
33
+ Unocss({
34
+ shortcuts: [
35
+ ['btn', 'px-4 py-1 rounded inline-flex justify-center gap-2 text-white leading-30px children:mya !no-underline cursor-pointer disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
36
+ ],
37
+ presets: [
38
+ presetUno({
39
+ dark: 'media',
40
+ }),
41
+ presetAttributify(),
42
+ presetIcons({
43
+ scale: 1.2,
44
+ }),
45
+ ],
46
+ }),
47
+ IncludesPlugin(),
48
+ ],
49
+ })
50
+
51
+ function IncludesPlugin(): Plugin {
52
+ return {
53
+ name: 'include-plugin',
54
+ enforce: 'pre',
55
+ transform(code, id) {
56
+ let changed = false
57
+ code = code.replace(/\[@@include\]\((.*?)\)/, (_, url) => {
58
+ changed = true
59
+ const full = resolve(id, url)
60
+ return fs.readFileSync(full, 'utf-8')
61
+ })
62
+ if (changed)
63
+ return code
64
+ },
65
+ }
66
+ }