@ruan-cat/utils 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/package.json CHANGED
@@ -1,24 +1,20 @@
1
1
  {
2
2
  "name": "@ruan-cat/utils",
3
- "version": "1.0.1",
4
- "description": "工具集合,预期是一个纯ts库,提供ts类型和ts的函数",
3
+ "version": "1.0.3",
4
+ "description": "阮喵喵工具集合。一个纯typescript库。",
5
5
  "type": "module",
6
- "_main": "./src/index.ts",
7
- "_types": "./src/index.ts",
8
- "_module": "./src",
9
6
  "main": "./src/index.ts",
10
7
  "types": "./src/index.ts",
11
8
  "exports": {
12
9
  ".": {
13
- "_import": "./src/index.ts",
14
- "_default": "./src/index.ts",
15
10
  "import": "./src/index.ts",
16
11
  "types": "./src/index.ts"
17
12
  },
18
- "./*": "./src/*"
13
+ "./src/*": "./src/*"
19
14
  },
20
15
  "keywords": [],
21
16
  "author": "ruan-cat",
17
+ "license": "MIT",
22
18
  "publishConfig": {
23
19
  "access": "public",
24
20
  "registry": "https://registry.npmjs.org/",
@@ -28,7 +24,18 @@
28
24
  "src",
29
25
  "tsconfig.json"
30
26
  ],
27
+ "devDependencies": {
28
+ "typedoc": "^0.25.13",
29
+ "typedoc-plugin-markdown": "^4.0.3",
30
+ "typescript": "^5.5.2"
31
+ },
31
32
  "scripts": {
32
- "test": "echo \"Error: no test specified\" && exit 1"
33
+ "typedoc": "typedoc",
34
+ "clean:type": "rimraf ./dist",
35
+ "generate:type-1": "vue-tsc -p tsconfig.json --composite false --declaration true --emitDeclarationOnly true",
36
+ "generate:type-2": "tsc -p tsconfig.json --composite false --declaration true --emitDeclarationOnly true",
37
+ "generate:type-3": "vue-tsc -p tsconfig.types.json",
38
+ "get-type": "pnpm clean:type && pnpm generate:type-3",
39
+ "rm:node_modules": "rimraf node_modules"
33
40
  }
34
41
  }
package/readme.md ADDED
@@ -0,0 +1,5 @@
1
+ # 工具包
2
+
3
+ ## TODO: 尝试开发一个 cli
4
+
5
+ - https://cloud.tencent.com/developer/article/2033881
package/src/conditions.ts CHANGED
@@ -1,4 +1,7 @@
1
- export type Conditions = Array<(...args: unknown[]) => boolean>;
1
+ export type Condition = (...args: unknown[]) => boolean;
2
+
3
+ /** @deprecated 没必要 */
4
+ export type Conditions = Condition[];
2
5
 
3
6
  /**
4
7
  * 是否每一个条件函数都满足?
@@ -14,10 +17,10 @@ export type Conditions = Array<(...args: unknown[]) => boolean>;
14
17
  * conditions.every((condition) => condition())
15
18
  * ```
16
19
  */
17
- export function isConditionsEvery(conditions: Conditions) {
20
+ export function isConditionsEvery(conditions: Condition[]) {
18
21
  return conditions.every((condition) => condition());
19
22
  }
20
23
 
21
- export function isConditionsSome(conditions: Conditions) {
24
+ export function isConditionsSome(conditions: Condition[]) {
22
25
  return conditions.some((condition) => condition());
23
26
  }
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- // https://stackoverflow.com/a/42731800/18167453
2
- // FIXME: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './conditions.js'?
3
- export * from "./conditions";
4
- export * from "./Prettify";
1
+ export * from "./rmmv-class-expand-tools.ts";
2
+ export * from "./conditions.ts";
3
+ export * from "./Prettify.ts";
@@ -0,0 +1,220 @@
1
+ import type { OptionalKeysOf } from "type-fest";
2
+ import { forIn, hasIn, isFunction, uniqueId } from "lodash-es";
3
+
4
+ /**
5
+ * rmmv特征基类
6
+ * @description
7
+ * 全部的rmmv类都具有 `initialize` 函数
8
+ *
9
+ * 此类型用于描述此
10
+ */
11
+ export declare abstract class RmmvClass {
12
+ initialize: (...args: any[]) => void;
13
+ }
14
+
15
+ /**
16
+ * 获取对象的全部函数key名称
17
+ * @description
18
+ * 从一个类型内,获取值为函数的key名称
19
+ */
20
+ export type FunctionKeys<T> = {
21
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
22
+ }[keyof T];
23
+
24
+ /**
25
+ * 属性提示工具
26
+ * @description
27
+ * 对继承的类进行属性提示
28
+ *
29
+ * 对自己新增的属性和函数做属性提示
30
+ *
31
+ * 对全部涉及到的函数,其this全部做判定
32
+ */
33
+ export type AttributePromptTool<SourceCode extends RmmvClass, UserCode> = ThisType<SourceCode & UserCode> &
34
+ Partial<SourceCode> &
35
+ UserCode;
36
+
37
+ type UserCodeClassAttributeType = {
38
+ counter: number;
39
+ drillCalendar: string[];
40
+ sayFuck: () => void;
41
+ isUserCodeClass(): true;
42
+ getDrillCalendar(): string[];
43
+ };
44
+
45
+ /**
46
+ * 默认处理策略
47
+ * @description
48
+ * 先回调rmmv源码 再加上用户代码
49
+ */
50
+ export const defaultHandleStrategy = <const>"source-first";
51
+
52
+ /**
53
+ * 处理策略
54
+ * @description
55
+ * 用户代码相对于rmmv源码的处理策略
56
+ */
57
+ const handleStrategy = <const>[
58
+ /** 用户代码覆盖掉rmmv源码 */
59
+ "userCode-cover-source",
60
+
61
+ defaultHandleStrategy,
62
+
63
+ /** 先执行用户代码 再回调rmmv源码 */
64
+ "userCode-first",
65
+ ];
66
+
67
+ /**
68
+ * 处理策略
69
+ * @description
70
+ * 用户代码相对于rmmv源码的处理策略
71
+ */
72
+ export type HandleStrategy = (typeof handleStrategy)[number];
73
+
74
+ function isSourceFirst(handleStrategy: HandleStrategy): handleStrategy is "source-first" {
75
+ return handleStrategy === "source-first";
76
+ }
77
+
78
+ function isUserCodeCoverSource(handleStrategy: HandleStrategy): handleStrategy is "userCode-cover-source" {
79
+ return handleStrategy === "userCode-cover-source";
80
+ }
81
+
82
+ function isUserCodeFirst(handleStrategy: HandleStrategy): handleStrategy is "userCode-first" {
83
+ return handleStrategy === "userCode-first";
84
+ }
85
+
86
+ /**
87
+ * 被默认执行默认处理策略的函数名
88
+ * @description
89
+ * 初始化函数默认使用固定的处理策略。
90
+ */
91
+ export type defaultHandleStrategy_FuncationName = FunctionKeys<RmmvClass>;
92
+
93
+ /** 全部可选字段组成的对象 且该对象的全部字段必填 */
94
+ type AllOptionalFieldObj<T extends object> = Required<Pick<T, OptionalKeysOf<T>>>;
95
+
96
+ /** 给一个对象排除 init 字段 */
97
+ type NoInit<T> = Omit<T, defaultHandleStrategy_FuncationName>;
98
+
99
+ type AllOptionalFieldObj_noInit<T extends object> = NoInit<AllOptionalFieldObj<T>>;
100
+
101
+ /** 处理策略配置的 全部有意义的配置键名 */
102
+ type HandleStrategyConfigKeys<T extends object> = FunctionKeys<AllOptionalFieldObj_noInit<T>>;
103
+
104
+ /**
105
+ * 全部有意义函数的 处理策略配置
106
+ * @description
107
+ * 只有可能去覆盖,拓展的函数名,才值得去配置
108
+ */
109
+ type HandleStrategyConfig<T extends object> = Record<HandleStrategyConfigKeys<T>, HandleStrategy>;
110
+
111
+ /** rmmv类拓展工具函数配置 */
112
+ type RmmvClassExpandTools<SourceCode extends new (...args: any[]) => RmmvClass, UserCode extends object> = {
113
+ /** 源码 一般是被拓展的类,往往是rmmv的源码类 */
114
+ source: SourceCode;
115
+
116
+ /** 用户代码 插件开发者编写的一个内部完备的对象 */
117
+ userCode: UserCode;
118
+
119
+ /**
120
+ * 拓展配置 按照要求拓展
121
+ * @description
122
+ * 用户可以不提供配置 就默认按照标准的方式处理
123
+ */
124
+ config?: Partial<HandleStrategyConfig<UserCode>>;
125
+ };
126
+
127
+ /** 函数别名存储对象 */
128
+ const functionAlias = new Map<string, Function>();
129
+
130
+ /** 生成函数别名id */
131
+ function generateFunctionAliasId(key: string) {
132
+ return uniqueId(`FunctionAliasId_${key}_`);
133
+ }
134
+
135
+ /**
136
+ * rmmv类拓展工具函数
137
+ * @description
138
+ * 预期处理5种情况
139
+ *
140
+ * - 1. 用户代码覆盖掉rmmv源码
141
+ * - 2. 默认处理策略
142
+ * - 3. 先执行用户代码 再回调rmmv源码
143
+ * - 4. 初始化函数默认使用固定的处理策略
144
+ * - 5. 继承对象没有这个属性时 说明是新的函数 直接添加到原型链上
145
+ */
146
+ export function rmmvClassExpandTools<
147
+ SourceCode extends new (...args: any[]) => RmmvClass,
148
+ UserCode extends object = any,
149
+ >(params: RmmvClassExpandTools<SourceCode, UserCode>) {
150
+ const { source, userCode, config } = params;
151
+ const handleStrategyConfig = config;
152
+
153
+ function getHandleStrategy(key: HandleStrategyConfigKeys<UserCode>): HandleStrategy {
154
+ return handleStrategyConfig?.[key] ?? defaultHandleStrategy;
155
+ }
156
+
157
+ /** 源对象的原型链 */
158
+ const sourcePrototype = source.prototype;
159
+
160
+ /** 属性是否在源对象的原型链内? */
161
+ function isInSourcePrototype(key: string) {
162
+ return hasIn(sourcePrototype, key);
163
+ }
164
+
165
+ /** 是不是初始化函数的名称? */
166
+ function isInitialize(key: string): key is defaultHandleStrategy_FuncationName {
167
+ return key === "initialize";
168
+ }
169
+
170
+ forIn(userCode, function (value, key, object: Record<string, any>) {
171
+ console.log(` value, key, object `, value, key);
172
+
173
+ // 继承对象有没有这个属性?
174
+ if (isInSourcePrototype(key)) {
175
+ if (isFunction(object[key])) {
176
+ const handleStrategy = getHandleStrategy(key as HandleStrategyConfigKeys<UserCode>);
177
+
178
+ // 1 用户代码覆盖掉rmmv源码
179
+ if (isUserCodeCoverSource(handleStrategy)) {
180
+ sourcePrototype[key] = value;
181
+ }
182
+
183
+ // 2 初始化函数默认使用固定的处理策略
184
+ // 3 默认处理策略
185
+ if (isInitialize(key) || isSourceFirst(handleStrategy)) {
186
+ const functionAliasId = generateFunctionAliasId(key);
187
+ functionAlias.set(functionAliasId, sourcePrototype[key]);
188
+
189
+ sourcePrototype[key] = function () {
190
+ console.log(` 进入到二次封装的函数 函数id = `, functionAliasId);
191
+ // 先回调rmmv源码
192
+ functionAlias.get(functionAliasId)!.apply(this, arguments);
193
+ value.apply(this, arguments);
194
+ };
195
+ }
196
+
197
+ // 4 先执行用户代码 再回调rmmv源码
198
+ if (isUserCodeFirst(handleStrategy)) {
199
+ const functionAliasId = generateFunctionAliasId(key);
200
+ functionAlias.set(functionAliasId, sourcePrototype[key]);
201
+
202
+ sourcePrototype[key] = function () {
203
+ console.log(` 进入到二次封装的函数 函数id = `, functionAliasId);
204
+ // 先执行用户代码
205
+ value.apply(this, arguments);
206
+ functionAlias.get(functionAliasId)!.apply(this, arguments);
207
+ };
208
+ }
209
+ }
210
+ } else {
211
+ if (isFunction(object[key])) {
212
+ /**
213
+ * 5 继承对象没有这个属性时 说明是新的函数
214
+ * 直接添加到原型链上
215
+ */
216
+ sourcePrototype[key] = value;
217
+ }
218
+ }
219
+ });
220
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ // 项目的根目录
5
+ "rootDir": ".",
6
+ // 项目基础目录
7
+ "baseUrl": ".",
8
+ "declaration": true,
9
+ "allowImportingTsExtensions": true,
10
+ "emitDeclarationOnly": true,
11
+ // tsc 编译产物输出目录
12
+ "outDir": "dist",
13
+ "checkJs": true,
14
+ // 项目包含了js
15
+ "allowJs": true,
16
+ "module": "nodenext",
17
+ "target": "ESNext",
18
+ // 模块解析策略
19
+ "moduleResolution": "NodeNext",
20
+ // 是否生成辅助 debug 的 .map.js 文件。
21
+ "sourceMap": false,
22
+ // 产物不消除注释
23
+ "removeComments": false,
24
+ // 严格模式类型检查,建议开启
25
+ "strict": true,
26
+ // 允许引入 .json 模块
27
+ "resolveJsonModule": true,
28
+ // 检查类型时是否跳过类型声明文件,一般在上游依赖存在类型问题时置为 true。
29
+ "skipLibCheck": true,
30
+ // 需要使用 ThisType 工具
31
+ "noImplicitThis": true,
32
+ "types": [
33
+ "typedoc",
34
+ "typedoc-plugin-markdown",
35
+ ],
36
+ "paths": {
37
+ "@/*": [
38
+ "./src/*"
39
+ ]
40
+ }
41
+ },
42
+ "include": [
43
+ "./src/**/*.ts",
44
+ "./tests/**/*.ts",
45
+ "./src/**/*.js",
46
+ "./tests/**/*.js",
47
+ // 尝试手动提供一个全局的类型声明。
48
+ "./tests/with-types/types/CanNewTypeByClass.d.ts",
49
+ ],
50
+ "exclude": [
51
+ "typedoc.config.cjs"
52
+ ]
53
+ }