@movk/core 1.0.1 → 1.0.3
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/bin/clean.mjs +90 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/package.json +19 -16
package/bin/clean.mjs
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { rm } from 'node:fs/promises'
|
|
3
|
+
import { relative, resolve } from 'node:path'
|
|
4
|
+
import process from 'node:process'
|
|
5
|
+
import fg from 'fast-glob'
|
|
6
|
+
|
|
7
|
+
const DEFAULT_TARGETS = [
|
|
8
|
+
'node_modules',
|
|
9
|
+
'.nuxt',
|
|
10
|
+
'.data',
|
|
11
|
+
'.output',
|
|
12
|
+
'.cache',
|
|
13
|
+
'dist',
|
|
14
|
+
'dist.zip'
|
|
15
|
+
]
|
|
16
|
+
const BATCH_SIZE = 10
|
|
17
|
+
|
|
18
|
+
async function removePath(path) {
|
|
19
|
+
try {
|
|
20
|
+
await rm(path, { recursive: true, force: true, maxRetries: 3 })
|
|
21
|
+
return { path, success: true }
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
if (e.code === 'ENOENT')
|
|
25
|
+
return { path, success: true }
|
|
26
|
+
return { path, success: false, error: e.message }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function processBatch(paths) {
|
|
31
|
+
const results = []
|
|
32
|
+
for (let i = 0; i < paths.length; i += BATCH_SIZE) {
|
|
33
|
+
const batch = paths.slice(i, i + BATCH_SIZE)
|
|
34
|
+
results.push(...await Promise.all(batch.map(removePath)))
|
|
35
|
+
}
|
|
36
|
+
return results
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function clean() {
|
|
40
|
+
const start = Date.now()
|
|
41
|
+
const args = process.argv.slice(2)
|
|
42
|
+
const targets = args.length > 0 ? args : DEFAULT_TARGETS
|
|
43
|
+
const root = resolve(process.cwd())
|
|
44
|
+
|
|
45
|
+
let paths
|
|
46
|
+
try {
|
|
47
|
+
paths = await fg(targets.map(t => `**/${t}`), {
|
|
48
|
+
cwd: root,
|
|
49
|
+
onlyFiles: false,
|
|
50
|
+
dot: true,
|
|
51
|
+
absolute: true,
|
|
52
|
+
ignore: ['**/node_modules/**/node_modules/**'],
|
|
53
|
+
suppressErrors: true
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.error('搜索失败:', e.message)
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!paths.length) {
|
|
62
|
+
console.log('未找到需要清理的目标')
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
paths = [...new Set(paths)].sort((a, b) => b.length - a.length)
|
|
67
|
+
|
|
68
|
+
const results = await processBatch(paths)
|
|
69
|
+
const removed = results.filter(r => r.success).length
|
|
70
|
+
const failed = results.filter(r => !r.success)
|
|
71
|
+
const duration = ((Date.now() - start) / 1000).toFixed(2)
|
|
72
|
+
|
|
73
|
+
console.log(`已清理 ${removed}/${results.length} 项,耗时 ${duration}s`)
|
|
74
|
+
|
|
75
|
+
if (failed.length) {
|
|
76
|
+
console.warn(`\n${failed.length} 项清理失败:`)
|
|
77
|
+
failed.forEach(f => console.warn(` ${relative(root, f.path)}: ${f.error}`))
|
|
78
|
+
process.exit(1)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
process.on('SIGINT', () => {
|
|
83
|
+
console.log('\n清理中断')
|
|
84
|
+
process.exit(130)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
clean().catch((e) => {
|
|
88
|
+
console.error('清理失败:', e.message)
|
|
89
|
+
process.exit(1)
|
|
90
|
+
})
|
package/dist/index.d.mts
CHANGED
|
@@ -231,7 +231,7 @@ type Merge<T, U> = Omit<T, keyof U> & U;
|
|
|
231
231
|
* type Test6 = IsPlainObject<null> // false
|
|
232
232
|
* ```
|
|
233
233
|
*/
|
|
234
|
-
type IsPlainObject<T> =
|
|
234
|
+
type IsPlainObject<T> = NonNullable<T> extends Record<string, any> ? NonNullable<T> extends any[] ? false : NonNullable<T> extends (...args: any[]) => any ? false : NonNullable<T> extends Date ? false : true : false;
|
|
235
235
|
/**
|
|
236
236
|
* 深度控制类型,用于限制类型递归的深度
|
|
237
237
|
* 防止类型计算超出 TypeScript 的递归限制
|
|
@@ -255,7 +255,7 @@ type Depth = [never, 0, 1, 2, 3, 4];
|
|
|
255
255
|
* ```
|
|
256
256
|
*/
|
|
257
257
|
type NestedKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
258
|
-
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${NestedKeys<T[K]
|
|
258
|
+
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${NestedKeys<NonNullable<T[K]>, Depth[D]>}` : K;
|
|
259
259
|
}[keyof T & string];
|
|
260
260
|
/**
|
|
261
261
|
* 提取对象中所有纯对象字段的键(包括嵌套的),支持点语法路径
|
|
@@ -279,7 +279,7 @@ type NestedKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
|
279
279
|
* ```
|
|
280
280
|
*/
|
|
281
281
|
type ObjectFieldKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
282
|
-
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${ObjectFieldKeys<T[K]
|
|
282
|
+
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${ObjectFieldKeys<NonNullable<T[K]>, Depth[D]>}` : never;
|
|
283
283
|
}[keyof T & string];
|
|
284
284
|
/**
|
|
285
285
|
* 提取对象中所有非对象字段的键
|
|
@@ -318,7 +318,7 @@ type NonObjectFieldKeys<T> = Exclude<NestedKeys<T>, ObjectFieldKeys<T>>;
|
|
|
318
318
|
* ```
|
|
319
319
|
*/
|
|
320
320
|
type ArrayFieldKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
321
|
-
[K in keyof T & string]:
|
|
321
|
+
[K in keyof T & string]: NonNullable<T[K]> extends any[] ? K : IsPlainObject<T[K]> extends true ? `${K}.${ArrayFieldKeys<NonNullable<T[K]>, Depth[D]>}` : never;
|
|
322
322
|
}[keyof T & string];
|
|
323
323
|
/**
|
|
324
324
|
* 根据路径字符串提取对象属性的类型,支持点语法和嵌套对象
|
package/dist/index.d.ts
CHANGED
|
@@ -231,7 +231,7 @@ type Merge<T, U> = Omit<T, keyof U> & U;
|
|
|
231
231
|
* type Test6 = IsPlainObject<null> // false
|
|
232
232
|
* ```
|
|
233
233
|
*/
|
|
234
|
-
type IsPlainObject<T> =
|
|
234
|
+
type IsPlainObject<T> = NonNullable<T> extends Record<string, any> ? NonNullable<T> extends any[] ? false : NonNullable<T> extends (...args: any[]) => any ? false : NonNullable<T> extends Date ? false : true : false;
|
|
235
235
|
/**
|
|
236
236
|
* 深度控制类型,用于限制类型递归的深度
|
|
237
237
|
* 防止类型计算超出 TypeScript 的递归限制
|
|
@@ -255,7 +255,7 @@ type Depth = [never, 0, 1, 2, 3, 4];
|
|
|
255
255
|
* ```
|
|
256
256
|
*/
|
|
257
257
|
type NestedKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
258
|
-
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${NestedKeys<T[K]
|
|
258
|
+
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${NestedKeys<NonNullable<T[K]>, Depth[D]>}` : K;
|
|
259
259
|
}[keyof T & string];
|
|
260
260
|
/**
|
|
261
261
|
* 提取对象中所有纯对象字段的键(包括嵌套的),支持点语法路径
|
|
@@ -279,7 +279,7 @@ type NestedKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
|
279
279
|
* ```
|
|
280
280
|
*/
|
|
281
281
|
type ObjectFieldKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
282
|
-
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${ObjectFieldKeys<T[K]
|
|
282
|
+
[K in keyof T & string]: IsPlainObject<T[K]> extends true ? K | `${K}.${ObjectFieldKeys<NonNullable<T[K]>, Depth[D]>}` : never;
|
|
283
283
|
}[keyof T & string];
|
|
284
284
|
/**
|
|
285
285
|
* 提取对象中所有非对象字段的键
|
|
@@ -318,7 +318,7 @@ type NonObjectFieldKeys<T> = Exclude<NestedKeys<T>, ObjectFieldKeys<T>>;
|
|
|
318
318
|
* ```
|
|
319
319
|
*/
|
|
320
320
|
type ArrayFieldKeys<T, D extends number = 2> = [D] extends [never] ? never : {
|
|
321
|
-
[K in keyof T & string]:
|
|
321
|
+
[K in keyof T & string]: NonNullable<T[K]> extends any[] ? K : IsPlainObject<T[K]> extends true ? `${K}.${ArrayFieldKeys<NonNullable<T[K]>, Depth[D]>}` : never;
|
|
322
322
|
}[keyof T & string];
|
|
323
323
|
/**
|
|
324
324
|
* 根据路径字符串提取对象属性的类型,支持点语法和嵌套对象
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@movk/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
5
|
-
"packageManager": "pnpm@10.
|
|
4
|
+
"version": "1.0.3",
|
|
5
|
+
"packageManager": "pnpm@10.26.2",
|
|
6
6
|
"description": "一个为现代 Vue.js 应用量身打造的高性能实用工具与组合式函数集合。",
|
|
7
7
|
"author": "YiXuan <mhaibaraai@gmail.com>",
|
|
8
8
|
"license": "MIT",
|
|
@@ -28,7 +28,11 @@
|
|
|
28
28
|
},
|
|
29
29
|
"main": "./dist/index.mjs",
|
|
30
30
|
"types": "./dist/index.d.mts",
|
|
31
|
+
"bin": {
|
|
32
|
+
"movk-clean": "./bin/clean.mjs"
|
|
33
|
+
},
|
|
31
34
|
"files": [
|
|
35
|
+
"bin",
|
|
32
36
|
"dist"
|
|
33
37
|
],
|
|
34
38
|
"scripts": {
|
|
@@ -39,29 +43,28 @@
|
|
|
39
43
|
"lint": "eslint .",
|
|
40
44
|
"lint:fix": "eslint . --fix",
|
|
41
45
|
"prepack": "nr build",
|
|
42
|
-
"release": "release-it && npm publish
|
|
43
|
-
"start": "tsx src/index.ts",
|
|
46
|
+
"release": "release-it && npm publish",
|
|
44
47
|
"typecheck": "tsc --noEmit && cd docs && nr typecheck",
|
|
45
48
|
"test": "vitest",
|
|
46
|
-
"clean": "
|
|
49
|
+
"clean": "node bin/clean.mjs"
|
|
47
50
|
},
|
|
48
51
|
"peerDependencies": {
|
|
49
|
-
"vue": "^3.5.
|
|
52
|
+
"vue": "^3.5.25"
|
|
50
53
|
},
|
|
51
54
|
"dependencies": {
|
|
52
|
-
"@vueuse/core": "^14.
|
|
53
|
-
"
|
|
55
|
+
"@vueuse/core": "^14.1.0",
|
|
56
|
+
"fast-glob": "^3.3.3",
|
|
57
|
+
"zod": "^4.2.1"
|
|
54
58
|
},
|
|
55
59
|
"devDependencies": {
|
|
56
|
-
"@antfu/eslint-config": "^6.
|
|
57
|
-
"@antfu/ni": "^
|
|
58
|
-
"@release-it/conventional-changelog": "^10.0.
|
|
59
|
-
"@types/node": "^24.10.
|
|
60
|
-
"eslint": "^9.39.
|
|
61
|
-
"release-it": "^19.
|
|
62
|
-
"tsx": "^4.20.6",
|
|
60
|
+
"@antfu/eslint-config": "^6.7.3",
|
|
61
|
+
"@antfu/ni": "^28.0.0",
|
|
62
|
+
"@release-it/conventional-changelog": "^10.0.4",
|
|
63
|
+
"@types/node": "^24.10.4",
|
|
64
|
+
"eslint": "^9.39.2",
|
|
65
|
+
"release-it": "^19.2.1",
|
|
63
66
|
"typescript": "^5.9.3",
|
|
64
67
|
"unbuild": "^3.6.1",
|
|
65
|
-
"vitest": "^4.0.
|
|
68
|
+
"vitest": "^4.0.16"
|
|
66
69
|
}
|
|
67
70
|
}
|