@gx-design-vue/create-gx-cli 0.1.2 → 0.1.4

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 (59) hide show
  1. package/README.md +4 -11
  2. package/package.json +3 -2
  3. package/src/main.js +9 -3
  4. package/template-mobile-vant-cli/.env +0 -0
  5. package/template-mobile-vant-cli/.env.pro +1 -1
  6. package/template-mobile-vant-cli/.env.production +2 -2
  7. package/template-mobile-vant-cli/.eslintignore +0 -1
  8. package/template-mobile-vant-cli/build/plugin/autoImport.ts +8 -10
  9. package/template-mobile-vant-cli/build/plugin/index.ts +2 -10
  10. package/template-mobile-vant-cli/build/plugin/mock.ts +5 -11
  11. package/template-mobile-vant-cli/build/plugin/viteMock/client.ts +88 -0
  12. package/template-mobile-vant-cli/build/plugin/viteMock/createMockServer.ts +271 -0
  13. package/template-mobile-vant-cli/build/plugin/viteMock/index.ts +69 -0
  14. package/template-mobile-vant-cli/build/plugin/viteMock/types.ts +48 -0
  15. package/template-mobile-vant-cli/build/plugin/viteMock/utils.ts +48 -0
  16. package/template-mobile-vant-cli/eslint.config.js +49 -0
  17. package/template-mobile-vant-cli/mock/_createProductionServer.ts +4 -4
  18. package/template-mobile-vant-cli/mock/datasSource/api/index.ts +0 -0
  19. package/template-mobile-vant-cli/package.json +26 -33
  20. package/template-mobile-vant-cli/src/components/PageContainer/ProSkeleton.tsx +1 -2
  21. package/template-mobile-vant-cli/src/components/PageContainer/index.tsx +7 -6
  22. package/template-mobile-vant-cli/src/components/PageContainer/style.module.less +1 -1
  23. package/template-mobile-vant-cli/src/core/vant-design/index.ts +1 -1
  24. package/template-mobile-vant-cli/src/hooks/web/usePageLoading.ts +8 -5
  25. package/template-mobile-vant-cli/src/layout/BasicLayout.vue +3 -3
  26. package/template-mobile-vant-cli/src/pages/home.vue +27 -27
  27. package/template-mobile-vant-cli/src/router/index.ts +3 -2
  28. package/template-mobile-vant-cli/src/router/typings.ts +1 -1
  29. package/template-mobile-vant-cli/src/settings/index.ts +2 -2
  30. package/template-mobile-vant-cli/src/store/modules/global.ts +1 -1
  31. package/template-mobile-vant-cli/src/utils/crypto/base64.ts +101 -0
  32. package/template-mobile-vant-cli/src/utils/{cryptoJS.ts → crypto/index.ts} +23 -5
  33. package/template-mobile-vant-cli/src/utils/env.ts +15 -17
  34. package/template-mobile-vant-cli/src/utils/pageTitle.ts +5 -3
  35. package/template-mobile-vant-cli/src/utils/request/XHR.ts +38 -30
  36. package/template-mobile-vant-cli/src/utils/request/axiosCancel.ts +32 -23
  37. package/template-mobile-vant-cli/src/utils/request/checkStatus.ts +1 -3
  38. package/template-mobile-vant-cli/src/utils/request/index.ts +3 -4
  39. package/template-mobile-vant-cli/src/utils/request/typings.ts +74 -17
  40. package/template-mobile-vant-cli/src/utils/storage.ts +25 -18
  41. package/template-mobile-vant-cli/src/utils/util.ts +0 -5
  42. package/template-mobile-vant-cli/src/utils/validate.ts +191 -3
  43. package/template-mobile-vant-cli/tsconfig.json +8 -9
  44. package/template-mobile-vant-cli/types/{gx-components.d.ts → ant-design-import.d.ts} +3 -3
  45. package/template-mobile-vant-cli/types/auto-imports.d.ts +3 -0
  46. package/template-mobile-vant-cli/types/components.d.ts +2 -5
  47. package/template-mobile-vant-cli/types/global.d.ts +7 -4
  48. package/template-mobile-vant-cli/types/module.d.ts +15 -2
  49. package/template-mobile-vant-cli/types/plugins-auto-import.d.ts +14 -0
  50. package/template-mobile-vant-cli/types/response.d.ts +8 -5
  51. package/template-mobile-vant-cli/types/vant-import.d.ts +13 -0
  52. package/template-mobile-vant-cli/unocss.config.ts +101 -0
  53. package/template-mobile-vant-cli/vite.config.ts +43 -11
  54. package/template-mobile-vant-cli/.eslintrc.js +0 -64
  55. package/template-mobile-vant-cli/.stylelintignore +0 -3
  56. package/template-mobile-vant-cli/mock/api/index.ts +0 -66
  57. package/template-mobile-vant-cli/stylelint.config.js +0 -106
  58. /package/template-mobile-vant-cli/{postcss.config.js → postcss.config.cjs} +0 -0
  59. /package/template-mobile-vant-cli/{prettier.config.js → prettier.config.cjs} +0 -0
package/README.md CHANGED
@@ -1,22 +1,15 @@
1
- # `@dkundel/create-project`
1
+ # `@gx-design-vue/create-gx-cli`
2
2
 
3
3
  🏗 Personal CLI to bootstrap new projects
4
4
 
5
5
  ## Installation & Usage
6
6
 
7
7
  ```bash
8
- npm init @dkundel/project
8
+ npm init @gx-design-vue/create-gx-cli
9
9
  # or
10
- npx @dkundel/create-project
10
+ npx @gx-design-vue/create-gx-cli
11
11
  # or
12
- npm install -g @dkundel/create-project
12
+ npm install -g @gx-design-vue/create-gx-cli
13
13
  create-project
14
14
  ```
15
15
 
16
- ## License
17
-
18
- MIT
19
-
20
- ## Collaborators
21
-
22
- - Dominik Kundel <hi@dominik.dev>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gx-design-vue/create-gx-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "description": "a cli to bootstrap gx project",
6
6
  "main": "src/index.js",
@@ -28,6 +28,7 @@
28
28
  "files": [
29
29
  "bin/",
30
30
  "src/",
31
- "template-*"
31
+ "template-mobile-vant-html/*",
32
+ "template-mobile-vant-cli/*"
32
33
  ]
33
34
  }
package/src/main.js CHANGED
@@ -13,7 +13,7 @@ const copy = promisify(ncp)
13
13
  const gitRepositoryList = [
14
14
  {
15
15
  name: 'gx-design-pro',
16
- git: 'https://gitee.com/gx12358/vue-antd-admin.git#v2'
16
+ git: 'https://gitee.com/gx12358/vue3-antd-admin.git'
17
17
  },
18
18
  {
19
19
  name: 'gx-design-thin',
@@ -22,8 +22,15 @@ const gitRepositoryList = [
22
22
  ]
23
23
 
24
24
  async function copyTemplateFiles(templateDir, root) {
25
+ const exclusions = [ 'node_modules' ]
25
26
  return copy(templateDir, root, {
26
- clobber: false
27
+ clobber: false,
28
+ filter: (sourcePath) => {
29
+ const relativePath = path.relative(templateDir, sourcePath);
30
+ const folders = relativePath.split(path.sep);
31
+ const folderToCheck = folders.length > 1 ? folders[1] : folders[0];
32
+ return !exclusions.includes(folderToCheck)
33
+ }
27
34
  })
28
35
  }
29
36
 
@@ -49,7 +56,6 @@ function editPackageJson(root, projectName) {
49
56
  writeFile(path.join(root, '.npmrc'), 'shamefully-hoist=true')
50
57
  }
51
58
 
52
-
53
59
  writeFile(path.join(root, 'package.json'), JSON.stringify(pkg, null, 2))
54
60
  }
55
61
  }
File without changes
@@ -2,7 +2,7 @@
2
2
  VITE_NODE_ENV= production
3
3
 
4
4
  # environment 代码环境
5
- VITE_USE_MODE = production
5
+ VITE_USE_MODE = pro
6
6
 
7
7
  VITE_USE_CDN= false
8
8
 
@@ -1,8 +1,8 @@
1
1
  # 实际执行环境 production
2
- VITE_NODE_ENV= test
2
+ VITE_NODE_ENV= production
3
3
 
4
4
  # environment 代码环境
5
- VITE_USE_MODE = test
5
+ VITE_USE_MODE = production
6
6
 
7
7
  VITE_USE_CDN= false
8
8
 
@@ -1,4 +1,3 @@
1
-
2
1
  *.sh
3
2
  node_modules
4
3
  *.md
@@ -2,25 +2,23 @@ import autoImport from 'unplugin-auto-import/vite'
2
2
  import Components from 'unplugin-vue-components/vite'
3
3
  import { VantResolver } from 'unplugin-vue-components/resolvers'
4
4
 
5
+ const importsModules = [ 'vue', 'vue-router' ] as any
6
+
5
7
  export function createAutoImport() {
6
8
  return [
7
9
  autoImport({
8
10
  include: [
9
11
  /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
10
12
  /\.vue$/, /\.vue\?vue/, // .vue
11
- /\.md$/, // .md
12
- ],
13
- imports: [
14
- 'vue',
15
- 'vue-router'
13
+ /\.md$/ // .md
16
14
  ],
17
- dts: 'types/auto-imports.d.ts'
15
+ imports: importsModules,
16
+ dts: 'types/auto-imports.d.ts',
17
+ dirs: [ 'src/store' ]
18
18
  }),
19
19
  Components({
20
- resolvers: [
21
- VantResolver()
22
- ],
23
- dts: 'types/components.d.ts'
20
+ resolvers: [ VantResolver() ],
21
+ dts: 'types/plugins-auto-import.d.ts'
24
22
  })
25
23
  ]
26
24
  }
@@ -5,7 +5,6 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
5
5
 
6
6
  import vueSetupExtend from 'vite-plugin-vue-setup-extend'
7
7
 
8
- import { presetAttributify, presetUno, transformerDirectives } from 'unocss'
9
8
  import Unocss from 'unocss/vite'
10
9
 
11
10
  import { configHtmlPlugin } from './html'
@@ -25,13 +24,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
25
24
  ]
26
25
 
27
26
  // unocss
28
- vitePlugins.push(Unocss({
29
- presets: [
30
- presetAttributify(),
31
- presetUno()
32
- ],
33
- transformers: [ transformerDirectives() ]
34
- }))
27
+ vitePlugins.push(Unocss())
35
28
 
36
29
  // vite-plugin-vue-setup-extend
37
30
  vitePlugins.push(vueSetupExtend())
@@ -40,8 +33,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
40
33
  vitePlugins.push(configHtmlPlugin(viteEnv, isBuild))
41
34
 
42
35
  // vite-plugin-mock
43
- VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild))
44
-
36
+ VITE_USE_MOCK && vitePlugins.push(configMockPlugin())
45
37
 
46
38
  // unplugin-auto-import/vite
47
39
  vitePlugins.push(createAutoImport())
@@ -1,20 +1,14 @@
1
- /**
2
- * Mock plugin for development and production.
3
- * https://github.com/anncwb/vite-plugin-mock
4
- */
5
- import { viteMockServe } from 'vite-plugin-mock'
1
+ import { viteMockServe } from './viteMock'
6
2
 
7
- export function configMockPlugin(isBuild: boolean) {
3
+ export function configMockPlugin() {
8
4
  return viteMockServe({
9
- ignore: /^\_/,
5
+ ignore: /^_/,
10
6
  mockPath: 'mock',
11
- watchFiles: true,
12
- localEnabled: !isBuild,
13
- prodEnabled: isBuild,
7
+ enable: true,
14
8
  injectCode: `
15
9
  import { setupProdMockServer } from '../mock/_createProductionServer';
16
10
 
17
11
  setupProdMockServer();
18
- `
12
+ `,
19
13
  })
20
14
  }
@@ -0,0 +1,88 @@
1
+ import mockJs from 'mockjs'
2
+ import { pathToRegexp } from 'path-to-regexp'
3
+
4
+ const Mock = mockJs as any
5
+
6
+ export function createProdMockServer(mockList: any[]) {
7
+ Mock.XHR.prototype.__send = Mock.XHR.prototype.send
8
+ Mock.XHR.prototype.send = function () {
9
+ if (this.custom.xhr) {
10
+ this.custom.xhr.withCredentials = this.withCredentials || false
11
+
12
+ if (this.responseType) {
13
+ this.custom.xhr.responseType = this.responseType
14
+ }
15
+ }
16
+ if (this.custom.requestHeaders) {
17
+ const headers: any = {}
18
+ for (let k in this.custom.requestHeaders) {
19
+ headers[k.toString().toLowerCase()] = this.custom.requestHeaders[k]
20
+ }
21
+ this.custom.options = Object.assign({}, this.custom.options, { headers })
22
+ }
23
+ this.__send.apply(this, arguments)
24
+ }
25
+
26
+ Mock.XHR.prototype.proxy_open = Mock.XHR.prototype.open
27
+
28
+ Mock.XHR.prototype.open = function () {
29
+ let responseType = this.responseType
30
+ this.proxy_open(...arguments)
31
+ if (this.custom.xhr) {
32
+ if (responseType) {
33
+ this.custom.xhr.responseType = responseType
34
+ }
35
+ }
36
+ }
37
+
38
+ for (const { url, method, response, timeout } of mockList) {
39
+ __setupMock__(timeout)
40
+ Mock.mock(
41
+ pathToRegexp(url, undefined, { end: false }),
42
+ method || 'get',
43
+ __XHR2ExpressReqWrapper__(response)
44
+ )
45
+ }
46
+ }
47
+
48
+ function __param2Obj__(url: string) {
49
+ const search = url.split('?')[1]
50
+ if (!search) {
51
+ return {}
52
+ }
53
+ return JSON.parse(
54
+ '{"' +
55
+ decodeURIComponent(search)
56
+ .replace(/"/g, '\\"')
57
+ .replace(/&/g, '","')
58
+ .replace(/=/g, '":"')
59
+ .replace(/\+/g, ' ') +
60
+ '"}'
61
+ )
62
+ }
63
+
64
+ function __XHR2ExpressReqWrapper__(handle: (d: any) => any) {
65
+ return function (options: any) {
66
+ let result = null
67
+ if (typeof handle === 'function') {
68
+ const { body, type, url, headers } = options
69
+ result = handle({
70
+ method: type,
71
+ body: JSON.parse(body),
72
+ query: __param2Obj__(url),
73
+ headers
74
+ })
75
+ } else {
76
+ result = handle
77
+ }
78
+
79
+ return Mock.mock(result)
80
+ }
81
+ }
82
+
83
+ function __setupMock__(timeout = 0) {
84
+ timeout &&
85
+ Mock.setup({
86
+ timeout
87
+ })
88
+ }
@@ -0,0 +1,271 @@
1
+ import type { MockMethod, Recordable, RespThisType, ViteMockOptions } from './types'
2
+ import path from 'node:path'
3
+ import fs from 'node:fs'
4
+ import chokidar from 'chokidar'
5
+ import colors from 'picocolors'
6
+ import url from 'node:url'
7
+ import fg from 'fast-glob'
8
+ import Mock from 'mockjs'
9
+ import type { ResolvedConfig } from 'vite'
10
+ import { match, pathToRegexp } from 'path-to-regexp'
11
+ import type { IncomingMessage, NextHandleFunction } from 'connect'
12
+ import type { GetOutputFile } from 'bundle-require'
13
+ import { bundleRequire, JS_EXT_RE } from 'bundle-require'
14
+ import { isAbsPath, isArray, isFunction, isRegExp, sleep } from './utils'
15
+
16
+ export let mockData: MockMethod[] = []
17
+
18
+ export async function createMockServer(
19
+ opt: ViteMockOptions = { mockPath: 'mock', configPath: 'vite.mock.config' },
20
+ config: ResolvedConfig,
21
+ ) {
22
+ opt = {
23
+ mockPath: 'mock',
24
+ watchFiles: true,
25
+ configPath: 'vite.mock.config.ts',
26
+ logger: true,
27
+ cors: true,
28
+ ...opt,
29
+ }
30
+
31
+ if (mockData.length > 0)
32
+ return
33
+ mockData = await getMockConfig(opt, config)
34
+ await createWatch(opt, config)
35
+ }
36
+
37
+ // request match
38
+ export async function requestMiddleware(opt: ViteMockOptions) {
39
+ const { logger = true } = opt
40
+ const middleware: NextHandleFunction = async (req, res, next) => {
41
+ let queryParams: {
42
+ query?: {
43
+ [key: string]: any
44
+ }
45
+ pathname?: string | null
46
+ } = {}
47
+
48
+ if (req.url) {
49
+ queryParams = url.parse(req.url, true)
50
+ }
51
+
52
+ const reqUrl = queryParams.pathname
53
+
54
+ const matchRequest = mockData.find((item) => {
55
+ if (!reqUrl || !item || !item.url) {
56
+ return false
57
+ }
58
+ if (item.method && item.method.toUpperCase() !== req.method) {
59
+ return false
60
+ }
61
+ return pathToRegexp(item.url).test(reqUrl)
62
+ })
63
+
64
+ if (matchRequest) {
65
+ const isGet = req.method && req.method.toUpperCase() === 'GET'
66
+ const { response, rawResponse, timeout, statusCode, url } = matchRequest
67
+
68
+ if (timeout) {
69
+ await sleep(timeout)
70
+ }
71
+
72
+ const urlMatch = match(url, { decode: decodeURIComponent })
73
+
74
+ let query = queryParams.query as any
75
+ if (reqUrl) {
76
+ if ((isGet && JSON.stringify(query) === '{}') || !isGet) {
77
+ const params = (urlMatch(reqUrl) as any).params
78
+ if (JSON.stringify(params) !== '{}') {
79
+ query = (urlMatch(reqUrl) as any).params || {}
80
+ } else {
81
+ query = queryParams.query || {}
82
+ }
83
+ }
84
+ }
85
+
86
+ const self: RespThisType = { req, res, parseJson: parseJson.bind(null, req) }
87
+ if (isFunction(rawResponse)) {
88
+ await rawResponse.bind(self)(req, res)
89
+ } else {
90
+ const body = await parseJson(req)
91
+ res.setHeader('Content-Type', 'application/json')
92
+ if (opt) {
93
+ res.setHeader('Access-Control-Allow-Credentials', true)
94
+ res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*')
95
+ }
96
+ res.statusCode = statusCode || 200
97
+ const mockResponse = isFunction(response)
98
+ ? response.bind(self)({ url: req.url as any, body, query, headers: req.headers })
99
+ : response
100
+ res.end(JSON.stringify(Mock.mock(mockResponse)))
101
+ }
102
+
103
+ logger && loggerOutput('request invoke', req.url!)
104
+ return
105
+ }
106
+ next()
107
+ }
108
+ return middleware
109
+ }
110
+
111
+ // create watch mock
112
+ function createWatch(opt: ViteMockOptions, config: ResolvedConfig) {
113
+ const { configPath, logger, watchFiles } = opt
114
+
115
+ if (!watchFiles) {
116
+ return
117
+ }
118
+
119
+ const { absConfigPath, absMockPath } = getPath(opt)
120
+
121
+ if (process.env.VITE_DISABLED_WATCH_MOCK === 'true') {
122
+ return
123
+ }
124
+
125
+ const watchDir = []
126
+ const exitsConfigPath = fs.existsSync(absConfigPath)
127
+
128
+ exitsConfigPath && configPath ? watchDir.push(absConfigPath) : watchDir.push(absMockPath)
129
+
130
+ const watcher = chokidar.watch(watchDir, {
131
+ ignoreInitial: true,
132
+ // ignore files generated by `bundle require`
133
+ ignored: '**/_*.bundled_*.(mjs|cjs)',
134
+ })
135
+
136
+ watcher.on('all', async (event, file) => {
137
+ logger && loggerOutput(`mock file ${event}`, file)
138
+ mockData = await getMockConfig(opt, config)
139
+ })
140
+ }
141
+
142
+ // clear cache
143
+ // function cleanRequireCache(opt: ViteMockOptions) {
144
+ // if (typeof require === 'undefined' || !require.cache) {
145
+ // return
146
+ // }
147
+ // const { absConfigPath, absMockPath } = getPath(opt)
148
+ // Object.keys(require.cache).forEach((file) => {
149
+ // if (file === absConfigPath || file.indexOf(absMockPath) > -1) {
150
+ // delete require.cache[file]
151
+ // }
152
+ // })
153
+ // }
154
+
155
+ function parseJson(req: IncomingMessage): Promise<Recordable> {
156
+ return new Promise((resolve) => {
157
+ let body = ''
158
+ let jsonStr = ''
159
+ req.on('data', function (chunk) {
160
+ body += chunk
161
+ })
162
+ req.on('end', function () {
163
+ try {
164
+ jsonStr = JSON.parse(body)
165
+ } catch (err) {
166
+ jsonStr = ''
167
+ }
168
+ resolve(jsonStr as any)
169
+ return
170
+ })
171
+ })
172
+ }
173
+
174
+ // load mock .ts files and watch
175
+ async function getMockConfig(opt: ViteMockOptions, config: ResolvedConfig) {
176
+ const { absConfigPath, absMockPath } = getPath(opt)
177
+ const { ignore, configPath, logger } = opt
178
+
179
+ let ret: MockMethod[] = []
180
+ if (configPath && fs.existsSync(absConfigPath)) {
181
+ logger && loggerOutput(`load mock data from`, absConfigPath)
182
+ ret = await resolveModule(absConfigPath, config)
183
+ return ret
184
+ }
185
+
186
+ const mockFiles = fg
187
+ .sync(`**/*.{ts,mjs,js}`, {
188
+ cwd: absMockPath,
189
+ })
190
+ .filter((item) => {
191
+ if (!ignore) {
192
+ return true
193
+ }
194
+ if (isFunction(ignore)) {
195
+ return !ignore(item)
196
+ }
197
+ if (isRegExp(ignore)) {
198
+ return !ignore.test(path.basename(item))
199
+ }
200
+ return true
201
+ })
202
+ try {
203
+ ret = []
204
+ const resolveModulePromiseList = []
205
+
206
+ for (let index = 0; index < mockFiles.length; index++) {
207
+ const mockFile = mockFiles[index]
208
+ resolveModulePromiseList.push(resolveModule(path.join(absMockPath, mockFile), config))
209
+ }
210
+ const loadAllResult = await Promise.all(resolveModulePromiseList)
211
+ for (const resultModule of loadAllResult) {
212
+ let mod = resultModule
213
+ if (!isArray(mod)) {
214
+ mod = [mod]
215
+ }
216
+ ret = [...ret, ...mod]
217
+ }
218
+ } catch (error: any) {
219
+ loggerOutput(`mock reload error`, error)
220
+ ret = []
221
+ }
222
+ return ret
223
+ }
224
+
225
+ // fixed file generation format
226
+ // use a random path to avoid import cache
227
+ const getOutputFile: GetOutputFile = (filepath, format) => {
228
+ const dirname = path.dirname(filepath)
229
+ const basename = path.basename(filepath)
230
+ const randomname = `${Date.now()}_${Math.random().toString(36).substring(2, 15)}`
231
+ return path.resolve(
232
+ dirname,
233
+ `_${basename.replace(JS_EXT_RE, `.bundled_${randomname}.${format === 'esm' ? 'mjs' : 'cjs'}`)}`,
234
+ )
235
+ }
236
+
237
+ // Inspired by vite
238
+ // support mock .ts files
239
+ async function resolveModule(p: string, config: ResolvedConfig): Promise<any> {
240
+ const mockData = await bundleRequire({
241
+ filepath: p,
242
+ getOutputFile,
243
+ })
244
+
245
+ let mod = mockData.mod.default || mockData.mod
246
+ if (isFunction(mod)) {
247
+ mod = await mod({ env: config.env, mode: config.mode, command: config.command })
248
+ }
249
+ return mod
250
+ }
251
+
252
+ // get custom config file path and mock dir path
253
+ function getPath(opt: ViteMockOptions) {
254
+ const { mockPath, configPath } = opt
255
+ const cwd = process.cwd()
256
+ const absMockPath = isAbsPath(mockPath) ? mockPath! : path.join(cwd, mockPath || '')
257
+ const absConfigPath = path.join(cwd, configPath || '')
258
+ return {
259
+ absMockPath,
260
+ absConfigPath,
261
+ }
262
+ }
263
+
264
+ function loggerOutput(title: string, msg: string, type: 'info' | 'error' = 'info') {
265
+ const tag = type === 'info' ? colors.cyan(`[vite:mock]`) : colors.red(`[vite:mock-server]`)
266
+ return console.log(
267
+ `${colors.dim(new Date().toLocaleTimeString())} ${tag} ${colors.green(title)} ${colors.dim(
268
+ msg,
269
+ )}`,
270
+ )
271
+ }
@@ -0,0 +1,69 @@
1
+ (async () => {
2
+ try {
3
+ await import('mockjs')
4
+ } catch (e) {
5
+ throw new Error('vite-plugin-vue-mock requires mockjs to be present in the dependency tree.')
6
+ }
7
+ })()
8
+
9
+ import type { Plugin, ResolvedConfig } from 'vite'
10
+ import { normalizePath } from 'vite'
11
+ import path from 'node:path'
12
+ import type { ViteMockOptions } from './types'
13
+ import { fileExists } from './utils'
14
+ import { createMockServer, requestMiddleware } from './createMockServer'
15
+
16
+ function getDefaultPath(supportTs = true) {
17
+ return path.resolve(process.cwd(), `src/main.${supportTs ? 'ts' : 'js'}`)
18
+ }
19
+
20
+ export function viteMockServe(opt: ViteMockOptions = {}): Plugin {
21
+ let isDev = false
22
+ let needSourcemap = false
23
+ let config: ResolvedConfig
24
+ let defaultPath = getDefaultPath()
25
+ if (!fileExists(defaultPath)) {
26
+ defaultPath = getDefaultPath(false)
27
+ if (!fileExists(defaultPath)) {
28
+ defaultPath = ''
29
+ }
30
+ }
31
+
32
+ const defaultEnter = normalizePath(defaultPath)
33
+
34
+ const { injectFile = defaultEnter } = opt
35
+
36
+ return {
37
+ name: 'vite:mock',
38
+ enforce: 'pre' as const,
39
+ configResolved(resolvedConfig) {
40
+ config = resolvedConfig
41
+ isDev = config.command === 'serve'
42
+ needSourcemap = !!resolvedConfig.build.sourcemap
43
+ isDev && createMockServer(opt, config)
44
+ },
45
+
46
+ configureServer: async ({ middlewares }) => {
47
+ const { enable = isDev } = opt
48
+ if (!enable) {
49
+ return
50
+ }
51
+ const middleware = await requestMiddleware(opt)
52
+ middlewares.use(middleware)
53
+ },
54
+ transform: (code, id) => {
55
+ if (isDev || !injectFile || !id.endsWith(injectFile)) {
56
+ return null
57
+ }
58
+
59
+ const { injectCode = '' } = opt
60
+
61
+ return {
62
+ map: needSourcemap ? this.getCombinedSourcemap() : null,
63
+ code: `${code}\n${injectCode}`
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ export * from './types'
@@ -0,0 +1,48 @@
1
+ import { IncomingMessage, ServerResponse } from 'http'
2
+
3
+ export interface ViteMockOptions {
4
+ mockPath?: string;
5
+ configPath?: string;
6
+ injectFile?: string;
7
+ injectCode?: string;
8
+ ignore?: RegExp | ((fileName: string) => boolean);
9
+ watchFiles?: boolean;
10
+ enable?: boolean;
11
+ cors?: boolean;
12
+ /**
13
+ * Automatic recognition, no need to configure again
14
+ * @deprecated Deprecated after 2.8.0
15
+ */
16
+ supportTs?: boolean;
17
+ logger?: boolean;
18
+ }
19
+
20
+ export interface RespThisType {
21
+ req: IncomingMessage
22
+ res: ServerResponse
23
+ parseJson: () => any
24
+ }
25
+
26
+ export type MethodType = 'get' | 'post' | 'put' | 'delete' | 'patch'
27
+
28
+ export type Recordable<T = any> = Record<string, T>
29
+
30
+ export declare interface MockMethod {
31
+ url: string
32
+ method?: MethodType
33
+ timeout?: number
34
+ statusCode?: number
35
+ response?:
36
+ | ((
37
+ this: RespThisType,
38
+ opt: { url: Recordable; body: Recordable; query: Recordable; headers: Recordable },
39
+ ) => any)
40
+ | any
41
+ rawResponse?: (this: RespThisType, req: IncomingMessage, res: ServerResponse) => void
42
+ }
43
+
44
+ export interface MockConfig {
45
+ env: Record<string, any>
46
+ mode: string
47
+ command: 'build' | 'serve'
48
+ }