@wevu/api 0.0.1 → 0.1.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.
package/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  ## 简介
4
4
 
5
- `@wevu/api` 是一个轻量的 API 包,目前主要用于提供基础导出与包结构示例,便于后续扩展。
5
+ `@wevu/api` 提供跨平台的小程序 API 封装,默认推荐 Promise 风格,同时兼容传统回调风格。
6
6
 
7
7
  ## 特性
8
8
 
9
- - 体积小、依赖少
10
- - 适合承载通用 API 或类型导出
11
- - 目前提供简单的示例导出
9
+ - 动态代理,覆盖微信小程序全量 API
10
+ - 跨平台适配(微信/支付宝/百度/字节/QQ/快应用/京东/小红书/快手/淘宝等)
11
+ - Promise 风格优先,回调风格可用
12
+ - 支持显式注入平台适配器
12
13
 
13
14
  ## 安装
14
15
 
@@ -18,16 +19,56 @@ pnpm add @wevu/api
18
19
 
19
20
  ## 使用
20
21
 
22
+ ### Promise 风格(推荐)
23
+
24
+ ```ts
25
+ import { wpi } from '@wevu/api'
26
+
27
+ const res = await wpi.request({
28
+ url: 'https://example.com',
29
+ method: 'GET',
30
+ })
31
+
32
+ console.log(res)
33
+ ```
34
+
35
+ ### 回调风格(兼容)
36
+
21
37
  ```ts
22
- import { greet, VERSION } from '@wevu/api'
38
+ import { wpi } from '@wevu/api'
39
+
40
+ wpi.request({
41
+ url: 'https://example.com',
42
+ method: 'GET',
43
+ success(res) {
44
+ console.log(res)
45
+ },
46
+ fail(err) {
47
+ console.error(err)
48
+ },
49
+ })
50
+ ```
51
+
52
+ ### 显式注入平台适配器
53
+
54
+ ```ts
55
+ import { createWeapi } from '@wevu/api'
56
+
57
+ const api = createWeapi({
58
+ adapter: wx,
59
+ platform: 'wx',
60
+ })
23
61
 
24
- console.log(greet('wevu'))
25
- console.log(VERSION)
62
+ await api.getSystemInfo()
26
63
  ```
27
64
 
28
- ## 配置
65
+ ## 行为说明
29
66
 
30
- 暂无额外配置。
67
+ - **只在不传回调时返回 Promise**
68
+ - 同步 API(`*Sync`)与事件 API(`onXxx/offXxx`)直接透传
69
+ - 缺失 API 时:
70
+ - 回调风格触发 `fail/complete`
71
+ - Promise 风格返回 rejected Promise
31
72
 
32
73
  ## 相关链接
33
74
 
package/dist/index.cjs CHANGED
@@ -1,16 +1,236 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
2
 
2
- //#region src/index.ts
3
+ //#region src/core/adapter.ts
4
+ const GLOBAL_ADAPTER_KEYS = [
5
+ {
6
+ platform: "wx",
7
+ key: "wx"
8
+ },
9
+ {
10
+ platform: "my",
11
+ key: "my"
12
+ },
13
+ {
14
+ platform: "tt",
15
+ key: "tt"
16
+ },
17
+ {
18
+ platform: "qq",
19
+ key: "qq"
20
+ },
21
+ {
22
+ platform: "swan",
23
+ key: "swan"
24
+ },
25
+ {
26
+ platform: "ks",
27
+ key: "ks"
28
+ },
29
+ {
30
+ platform: "jd",
31
+ key: "jd"
32
+ },
33
+ {
34
+ platform: "xhs",
35
+ key: "xhs"
36
+ },
37
+ {
38
+ platform: "dd",
39
+ key: "dd"
40
+ },
41
+ {
42
+ platform: "qa",
43
+ key: "qa"
44
+ },
45
+ {
46
+ platform: "qapp",
47
+ key: "qapp"
48
+ },
49
+ {
50
+ platform: "uni",
51
+ key: "uni"
52
+ }
53
+ ];
54
+ function resolveGlobalThis() {
55
+ if (typeof globalThis !== "undefined") return globalThis;
56
+ if (typeof window !== "undefined") return window;
57
+ }
58
+ function isAdapterCandidate(value) {
59
+ return typeof value === "object" || typeof value === "function";
60
+ }
3
61
  /**
4
- * @description 简单的问候函数
62
+ * @description 侦测当前运行环境的全局 API 对象
5
63
  */
6
- function greet(name) {
7
- return `hello ${name}`;
64
+ function detectGlobalAdapter() {
65
+ const root = resolveGlobalThis();
66
+ if (!root) return {};
67
+ for (const item of GLOBAL_ADAPTER_KEYS) {
68
+ const candidate = root[item.key];
69
+ if (isAdapterCandidate(candidate)) return {
70
+ adapter: candidate,
71
+ platform: item.platform
72
+ };
73
+ }
74
+ return {};
75
+ }
76
+
77
+ //#endregion
78
+ //#region src/core/utils.ts
79
+ function isPlainObject(value) {
80
+ return Object.prototype.toString.call(value) === "[object Object]";
8
81
  }
82
+ function hasCallbacks(value) {
83
+ if (!isPlainObject(value)) return false;
84
+ return typeof value.success === "function" || typeof value.fail === "function" || typeof value.complete === "function";
85
+ }
86
+ function isSyncMethod(name) {
87
+ return name.endsWith("Sync");
88
+ }
89
+ function isEventMethod(name) {
90
+ return /^on[A-Z]/.test(name) || /^off[A-Z]/.test(name);
91
+ }
92
+ function shouldSkipPromise(name) {
93
+ return isSyncMethod(name) || isEventMethod(name);
94
+ }
95
+ function createNotSupportedError(methodName, platform) {
96
+ return { errMsg: `${platform ? `${platform}.${methodName}` : methodName}:fail method not supported` };
97
+ }
98
+
99
+ //#endregion
100
+ //#region src/core/createWeapi.ts
101
+ const INTERNAL_KEYS = new Set([
102
+ "setAdapter",
103
+ "getAdapter",
104
+ "platform",
105
+ "raw"
106
+ ]);
107
+ function normalizePlatformName(value) {
108
+ return value || void 0;
109
+ }
110
+ function resolveOptionsArg(args) {
111
+ const nextArgs = args.slice();
112
+ const lastArg = nextArgs.length > 0 ? nextArgs[nextArgs.length - 1] : void 0;
113
+ if (isPlainObject(lastArg)) {
114
+ const options = { ...lastArg };
115
+ nextArgs[nextArgs.length - 1] = options;
116
+ return {
117
+ args: nextArgs,
118
+ options
119
+ };
120
+ }
121
+ const options = {};
122
+ nextArgs.push(options);
123
+ return {
124
+ args: nextArgs,
125
+ options
126
+ };
127
+ }
128
+ function callWithPromise(context, method, args) {
129
+ return new Promise((resolve, reject) => {
130
+ const { args: nextArgs, options } = resolveOptionsArg(args);
131
+ let settled = false;
132
+ options.success = (res) => {
133
+ settled = true;
134
+ resolve(res);
135
+ };
136
+ options.fail = (err) => {
137
+ settled = true;
138
+ reject(err);
139
+ };
140
+ options.complete = (res) => {
141
+ if (!settled) resolve(res);
142
+ };
143
+ try {
144
+ method.apply(context, nextArgs);
145
+ } catch (err) {
146
+ reject(err);
147
+ }
148
+ });
149
+ }
150
+ function callMissingApi(methodName, platform, args) {
151
+ const lastArg = args.length > 0 ? args[args.length - 1] : void 0;
152
+ const error = createNotSupportedError(methodName, platform);
153
+ if (hasCallbacks(lastArg)) {
154
+ lastArg.fail?.(error);
155
+ lastArg.complete?.(error);
156
+ return;
157
+ }
158
+ return Promise.reject(error);
159
+ }
160
+ /**
161
+ * @description 创建跨平台 API 实例
162
+ */
163
+ function createWeapi(options = {}) {
164
+ let adapter = options.adapter;
165
+ let platformName = normalizePlatformName(options.platform);
166
+ const cache = /* @__PURE__ */ new Map();
167
+ const resolveAdapter = () => {
168
+ if (adapter) return adapter;
169
+ const detected = detectGlobalAdapter();
170
+ if (detected.adapter) {
171
+ adapter = detected.adapter;
172
+ platformName = platformName ?? normalizePlatformName(detected.platform);
173
+ }
174
+ return adapter;
175
+ };
176
+ const setAdapter = (nextAdapter, nextPlatform) => {
177
+ adapter = nextAdapter;
178
+ platformName = normalizePlatformName(nextPlatform);
179
+ cache.clear();
180
+ };
181
+ const getAdapter = () => {
182
+ if (!adapter) resolveAdapter();
183
+ return adapter;
184
+ };
185
+ const getPlatform = () => {
186
+ if (!platformName) resolveAdapter();
187
+ return platformName;
188
+ };
189
+ return new Proxy({}, { get(_target, prop) {
190
+ if (prop === Symbol.toStringTag) return "Weapi";
191
+ if (prop === "then") return;
192
+ if (INTERNAL_KEYS.has(prop)) {
193
+ if (prop === "setAdapter") return setAdapter;
194
+ if (prop === "getAdapter") return getAdapter;
195
+ if (prop === "platform") return getPlatform();
196
+ if (prop === "raw") return getAdapter();
197
+ }
198
+ if (cache.has(prop)) return cache.get(prop);
199
+ const currentAdapter = resolveAdapter();
200
+ if (!currentAdapter) {
201
+ if (typeof prop !== "string") return;
202
+ return (...args) => callMissingApi(prop, getPlatform(), args);
203
+ }
204
+ const value = currentAdapter[prop];
205
+ if (typeof value !== "function") {
206
+ if (value === void 0 && typeof prop === "string") {
207
+ const missing = (...args) => callMissingApi(prop, getPlatform(), args);
208
+ cache.set(prop, missing);
209
+ return missing;
210
+ }
211
+ cache.set(prop, value);
212
+ return value;
213
+ }
214
+ const wrapped = (...args) => {
215
+ const runtimeAdapter = resolveAdapter();
216
+ const runtimeMethod = runtimeAdapter ? runtimeAdapter[prop] : void 0;
217
+ if (typeof runtimeMethod !== "function") return callMissingApi(prop, getPlatform(), args);
218
+ if (shouldSkipPromise(prop)) return runtimeMethod.apply(runtimeAdapter, args);
219
+ if (hasCallbacks(args.length > 0 ? args[args.length - 1] : void 0)) return runtimeMethod.apply(runtimeAdapter, args);
220
+ return callWithPromise(runtimeAdapter, runtimeMethod, args);
221
+ };
222
+ cache.set(prop, wrapped);
223
+ return wrapped;
224
+ } });
225
+ }
226
+
227
+ //#endregion
228
+ //#region src/index.ts
9
229
  /**
10
- * @description 当前包版本号
230
+ * @description 默认跨平台 API 实例(推荐使用)
11
231
  */
12
- const VERSION = "0.0.0";
232
+ const wpi = createWeapi();
13
233
 
14
234
  //#endregion
15
- exports.VERSION = VERSION;
16
- exports.greet = greet;
235
+ exports.createWeapi = createWeapi;
236
+ exports.wpi = wpi;
package/dist/index.d.cts CHANGED
@@ -1,11 +1,71 @@
1
- //#region src/index.d.ts
1
+ //#region src/core/types.d.ts
2
+ type WeapiAdapter = Record<string, any>;
3
+ /**
4
+ * @description 微信小程序 API 原始适配器类型
5
+ */
6
+ type WeapiWxRawAdapter = WechatMiniprogram.Wx;
7
+ type HasCallbackKey<T> = T extends object ? 'success' extends keyof T ? true : 'fail' extends keyof T ? true : 'complete' extends keyof T ? true : false : false;
8
+ type HasCallbackOption<T> = T extends {
9
+ success: unknown;
10
+ } ? true : T extends {
11
+ fail: unknown;
12
+ } ? true : T extends {
13
+ complete: unknown;
14
+ } ? true : false;
15
+ type ExtractSuccessResult<T> = T extends {
16
+ success?: (...args: infer A) => unknown;
17
+ } ? A[0] : void;
18
+ type PromisifyOptionMethod<Prefix extends any[], Option extends object, Result, IsOptional extends boolean> = IsOptional extends true ? {
19
+ <TOption extends Option>(...args: [...Prefix, TOption]): HasCallbackOption<TOption> extends true ? Result : Promise<ExtractSuccessResult<Option>>;
20
+ (...args: Prefix): Promise<ExtractSuccessResult<Option>>;
21
+ } : {
22
+ <TOption extends Option>(...args: [...Prefix, TOption]): HasCallbackOption<TOption> extends true ? Result : Promise<ExtractSuccessResult<Option>>;
23
+ };
24
+ type PromisifyMethod<TMethod> = TMethod extends ((...args: infer Args) => infer Result) ? Args extends [] ? (...args: Args) => Promise<Result> : Args extends [...infer Prefix, infer Last] ? true extends HasCallbackKey<NonNullable<Last>> ? PromisifyOptionMethod<Prefix, NonNullable<Last>, Result, undefined extends Last ? true : false> : (...args: Args) => Promise<Result> : (...args: Args) => Promise<Result> : TMethod;
25
+ type WeapiPromisify<TAdapter extends WeapiAdapter> = { [Key in keyof TAdapter]: Key extends string ? Key extends `${string}Sync` ? TAdapter[Key] : Key extends `on${Capitalize<string>}` | `off${Capitalize<string>}` ? TAdapter[Key] : PromisifyMethod<TAdapter[Key]> : TAdapter[Key] };
26
+ /**
27
+ * @description 微信小程序 API 适配器类型
28
+ */
29
+ type WeapiWxAdapter = WeapiPromisify<WeapiWxRawAdapter>;
30
+ interface CreateWeapiOptions<TAdapter extends WeapiAdapter = WeapiWxRawAdapter> {
31
+ /**
32
+ * @description 手动指定平台适配器(优先级高于自动探测)
33
+ */
34
+ adapter?: TAdapter;
35
+ /**
36
+ * @description 手动指定平台名称
37
+ */
38
+ platform?: string;
39
+ }
40
+ type WeapiInstance<TAdapter extends WeapiAdapter = WeapiWxRawAdapter> = WeapiPromisify<TAdapter> & {
41
+ /**
42
+ * @description 当前平台标识
43
+ */
44
+ readonly platform?: string;
45
+ /**
46
+ * @description 获取当前适配器实例
47
+ */
48
+ getAdapter: () => TAdapter | undefined;
49
+ /**
50
+ * @description 手动替换平台适配器
51
+ */
52
+ setAdapter: (adapter?: TAdapter, platform?: string) => void;
53
+ /**
54
+ * @description 获取原始平台对象
55
+ */
56
+ readonly raw?: TAdapter;
57
+ };
58
+ //#endregion
59
+ //#region src/core/createWeapi.d.ts
2
60
  /**
3
- * @description 简单的问候函数
61
+ * @description 创建跨平台 API 实例
4
62
  */
5
- declare function greet(name: string): string;
63
+ declare function createWeapi<TAdapter extends WeapiAdapter = WeapiWxRawAdapter>(options?: CreateWeapiOptions<TAdapter>): WeapiInstance<TAdapter>;
64
+ //#endregion
65
+ //#region src/index.d.ts
6
66
  /**
7
- * @description 当前包版本号
67
+ * @description 默认跨平台 API 实例(推荐使用)
8
68
  */
9
- declare const VERSION = "0.0.0";
69
+ declare const wpi: WeapiInstance<WechatMiniprogram.Wx>;
10
70
  //#endregion
11
- export { VERSION, greet };
71
+ export { type CreateWeapiOptions, type WeapiAdapter, type WeapiInstance, type WeapiPromisify, type WeapiWxAdapter, type WeapiWxRawAdapter, createWeapi, wpi };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,71 @@
1
- //#region src/index.d.ts
1
+ //#region src/core/types.d.ts
2
+ type WeapiAdapter = Record<string, any>;
3
+ /**
4
+ * @description 微信小程序 API 原始适配器类型
5
+ */
6
+ type WeapiWxRawAdapter = WechatMiniprogram.Wx;
7
+ type HasCallbackKey<T> = T extends object ? 'success' extends keyof T ? true : 'fail' extends keyof T ? true : 'complete' extends keyof T ? true : false : false;
8
+ type HasCallbackOption<T> = T extends {
9
+ success: unknown;
10
+ } ? true : T extends {
11
+ fail: unknown;
12
+ } ? true : T extends {
13
+ complete: unknown;
14
+ } ? true : false;
15
+ type ExtractSuccessResult<T> = T extends {
16
+ success?: (...args: infer A) => unknown;
17
+ } ? A[0] : void;
18
+ type PromisifyOptionMethod<Prefix extends any[], Option extends object, Result, IsOptional extends boolean> = IsOptional extends true ? {
19
+ <TOption extends Option>(...args: [...Prefix, TOption]): HasCallbackOption<TOption> extends true ? Result : Promise<ExtractSuccessResult<Option>>;
20
+ (...args: Prefix): Promise<ExtractSuccessResult<Option>>;
21
+ } : {
22
+ <TOption extends Option>(...args: [...Prefix, TOption]): HasCallbackOption<TOption> extends true ? Result : Promise<ExtractSuccessResult<Option>>;
23
+ };
24
+ type PromisifyMethod<TMethod> = TMethod extends ((...args: infer Args) => infer Result) ? Args extends [] ? (...args: Args) => Promise<Result> : Args extends [...infer Prefix, infer Last] ? true extends HasCallbackKey<NonNullable<Last>> ? PromisifyOptionMethod<Prefix, NonNullable<Last>, Result, undefined extends Last ? true : false> : (...args: Args) => Promise<Result> : (...args: Args) => Promise<Result> : TMethod;
25
+ type WeapiPromisify<TAdapter extends WeapiAdapter> = { [Key in keyof TAdapter]: Key extends string ? Key extends `${string}Sync` ? TAdapter[Key] : Key extends `on${Capitalize<string>}` | `off${Capitalize<string>}` ? TAdapter[Key] : PromisifyMethod<TAdapter[Key]> : TAdapter[Key] };
26
+ /**
27
+ * @description 微信小程序 API 适配器类型
28
+ */
29
+ type WeapiWxAdapter = WeapiPromisify<WeapiWxRawAdapter>;
30
+ interface CreateWeapiOptions<TAdapter extends WeapiAdapter = WeapiWxRawAdapter> {
31
+ /**
32
+ * @description 手动指定平台适配器(优先级高于自动探测)
33
+ */
34
+ adapter?: TAdapter;
35
+ /**
36
+ * @description 手动指定平台名称
37
+ */
38
+ platform?: string;
39
+ }
40
+ type WeapiInstance<TAdapter extends WeapiAdapter = WeapiWxRawAdapter> = WeapiPromisify<TAdapter> & {
41
+ /**
42
+ * @description 当前平台标识
43
+ */
44
+ readonly platform?: string;
45
+ /**
46
+ * @description 获取当前适配器实例
47
+ */
48
+ getAdapter: () => TAdapter | undefined;
49
+ /**
50
+ * @description 手动替换平台适配器
51
+ */
52
+ setAdapter: (adapter?: TAdapter, platform?: string) => void;
53
+ /**
54
+ * @description 获取原始平台对象
55
+ */
56
+ readonly raw?: TAdapter;
57
+ };
58
+ //#endregion
59
+ //#region src/core/createWeapi.d.ts
2
60
  /**
3
- * @description 简单的问候函数
61
+ * @description 创建跨平台 API 实例
4
62
  */
5
- declare function greet(name: string): string;
63
+ declare function createWeapi<TAdapter extends WeapiAdapter = WeapiWxRawAdapter>(options?: CreateWeapiOptions<TAdapter>): WeapiInstance<TAdapter>;
64
+ //#endregion
65
+ //#region src/index.d.ts
6
66
  /**
7
- * @description 当前包版本号
67
+ * @description 默认跨平台 API 实例(推荐使用)
8
68
  */
9
- declare const VERSION = "0.0.0";
69
+ declare const wpi: WeapiInstance<WechatMiniprogram.Wx>;
10
70
  //#endregion
11
- export { VERSION, greet };
71
+ export { type CreateWeapiOptions, type WeapiAdapter, type WeapiInstance, type WeapiPromisify, type WeapiWxAdapter, type WeapiWxRawAdapter, createWeapi, wpi };
package/dist/index.mjs CHANGED
@@ -1,14 +1,233 @@
1
- //#region src/index.ts
1
+ //#region src/core/adapter.ts
2
+ const GLOBAL_ADAPTER_KEYS = [
3
+ {
4
+ platform: "wx",
5
+ key: "wx"
6
+ },
7
+ {
8
+ platform: "my",
9
+ key: "my"
10
+ },
11
+ {
12
+ platform: "tt",
13
+ key: "tt"
14
+ },
15
+ {
16
+ platform: "qq",
17
+ key: "qq"
18
+ },
19
+ {
20
+ platform: "swan",
21
+ key: "swan"
22
+ },
23
+ {
24
+ platform: "ks",
25
+ key: "ks"
26
+ },
27
+ {
28
+ platform: "jd",
29
+ key: "jd"
30
+ },
31
+ {
32
+ platform: "xhs",
33
+ key: "xhs"
34
+ },
35
+ {
36
+ platform: "dd",
37
+ key: "dd"
38
+ },
39
+ {
40
+ platform: "qa",
41
+ key: "qa"
42
+ },
43
+ {
44
+ platform: "qapp",
45
+ key: "qapp"
46
+ },
47
+ {
48
+ platform: "uni",
49
+ key: "uni"
50
+ }
51
+ ];
52
+ function resolveGlobalThis() {
53
+ if (typeof globalThis !== "undefined") return globalThis;
54
+ if (typeof window !== "undefined") return window;
55
+ }
56
+ function isAdapterCandidate(value) {
57
+ return typeof value === "object" || typeof value === "function";
58
+ }
2
59
  /**
3
- * @description 简单的问候函数
60
+ * @description 侦测当前运行环境的全局 API 对象
4
61
  */
5
- function greet(name) {
6
- return `hello ${name}`;
62
+ function detectGlobalAdapter() {
63
+ const root = resolveGlobalThis();
64
+ if (!root) return {};
65
+ for (const item of GLOBAL_ADAPTER_KEYS) {
66
+ const candidate = root[item.key];
67
+ if (isAdapterCandidate(candidate)) return {
68
+ adapter: candidate,
69
+ platform: item.platform
70
+ };
71
+ }
72
+ return {};
73
+ }
74
+
75
+ //#endregion
76
+ //#region src/core/utils.ts
77
+ function isPlainObject(value) {
78
+ return Object.prototype.toString.call(value) === "[object Object]";
7
79
  }
80
+ function hasCallbacks(value) {
81
+ if (!isPlainObject(value)) return false;
82
+ return typeof value.success === "function" || typeof value.fail === "function" || typeof value.complete === "function";
83
+ }
84
+ function isSyncMethod(name) {
85
+ return name.endsWith("Sync");
86
+ }
87
+ function isEventMethod(name) {
88
+ return /^on[A-Z]/.test(name) || /^off[A-Z]/.test(name);
89
+ }
90
+ function shouldSkipPromise(name) {
91
+ return isSyncMethod(name) || isEventMethod(name);
92
+ }
93
+ function createNotSupportedError(methodName, platform) {
94
+ return { errMsg: `${platform ? `${platform}.${methodName}` : methodName}:fail method not supported` };
95
+ }
96
+
97
+ //#endregion
98
+ //#region src/core/createWeapi.ts
99
+ const INTERNAL_KEYS = new Set([
100
+ "setAdapter",
101
+ "getAdapter",
102
+ "platform",
103
+ "raw"
104
+ ]);
105
+ function normalizePlatformName(value) {
106
+ return value || void 0;
107
+ }
108
+ function resolveOptionsArg(args) {
109
+ const nextArgs = args.slice();
110
+ const lastArg = nextArgs.length > 0 ? nextArgs[nextArgs.length - 1] : void 0;
111
+ if (isPlainObject(lastArg)) {
112
+ const options = { ...lastArg };
113
+ nextArgs[nextArgs.length - 1] = options;
114
+ return {
115
+ args: nextArgs,
116
+ options
117
+ };
118
+ }
119
+ const options = {};
120
+ nextArgs.push(options);
121
+ return {
122
+ args: nextArgs,
123
+ options
124
+ };
125
+ }
126
+ function callWithPromise(context, method, args) {
127
+ return new Promise((resolve, reject) => {
128
+ const { args: nextArgs, options } = resolveOptionsArg(args);
129
+ let settled = false;
130
+ options.success = (res) => {
131
+ settled = true;
132
+ resolve(res);
133
+ };
134
+ options.fail = (err) => {
135
+ settled = true;
136
+ reject(err);
137
+ };
138
+ options.complete = (res) => {
139
+ if (!settled) resolve(res);
140
+ };
141
+ try {
142
+ method.apply(context, nextArgs);
143
+ } catch (err) {
144
+ reject(err);
145
+ }
146
+ });
147
+ }
148
+ function callMissingApi(methodName, platform, args) {
149
+ const lastArg = args.length > 0 ? args[args.length - 1] : void 0;
150
+ const error = createNotSupportedError(methodName, platform);
151
+ if (hasCallbacks(lastArg)) {
152
+ lastArg.fail?.(error);
153
+ lastArg.complete?.(error);
154
+ return;
155
+ }
156
+ return Promise.reject(error);
157
+ }
158
+ /**
159
+ * @description 创建跨平台 API 实例
160
+ */
161
+ function createWeapi(options = {}) {
162
+ let adapter = options.adapter;
163
+ let platformName = normalizePlatformName(options.platform);
164
+ const cache = /* @__PURE__ */ new Map();
165
+ const resolveAdapter = () => {
166
+ if (adapter) return adapter;
167
+ const detected = detectGlobalAdapter();
168
+ if (detected.adapter) {
169
+ adapter = detected.adapter;
170
+ platformName = platformName ?? normalizePlatformName(detected.platform);
171
+ }
172
+ return adapter;
173
+ };
174
+ const setAdapter = (nextAdapter, nextPlatform) => {
175
+ adapter = nextAdapter;
176
+ platformName = normalizePlatformName(nextPlatform);
177
+ cache.clear();
178
+ };
179
+ const getAdapter = () => {
180
+ if (!adapter) resolveAdapter();
181
+ return adapter;
182
+ };
183
+ const getPlatform = () => {
184
+ if (!platformName) resolveAdapter();
185
+ return platformName;
186
+ };
187
+ return new Proxy({}, { get(_target, prop) {
188
+ if (prop === Symbol.toStringTag) return "Weapi";
189
+ if (prop === "then") return;
190
+ if (INTERNAL_KEYS.has(prop)) {
191
+ if (prop === "setAdapter") return setAdapter;
192
+ if (prop === "getAdapter") return getAdapter;
193
+ if (prop === "platform") return getPlatform();
194
+ if (prop === "raw") return getAdapter();
195
+ }
196
+ if (cache.has(prop)) return cache.get(prop);
197
+ const currentAdapter = resolveAdapter();
198
+ if (!currentAdapter) {
199
+ if (typeof prop !== "string") return;
200
+ return (...args) => callMissingApi(prop, getPlatform(), args);
201
+ }
202
+ const value = currentAdapter[prop];
203
+ if (typeof value !== "function") {
204
+ if (value === void 0 && typeof prop === "string") {
205
+ const missing = (...args) => callMissingApi(prop, getPlatform(), args);
206
+ cache.set(prop, missing);
207
+ return missing;
208
+ }
209
+ cache.set(prop, value);
210
+ return value;
211
+ }
212
+ const wrapped = (...args) => {
213
+ const runtimeAdapter = resolveAdapter();
214
+ const runtimeMethod = runtimeAdapter ? runtimeAdapter[prop] : void 0;
215
+ if (typeof runtimeMethod !== "function") return callMissingApi(prop, getPlatform(), args);
216
+ if (shouldSkipPromise(prop)) return runtimeMethod.apply(runtimeAdapter, args);
217
+ if (hasCallbacks(args.length > 0 ? args[args.length - 1] : void 0)) return runtimeMethod.apply(runtimeAdapter, args);
218
+ return callWithPromise(runtimeAdapter, runtimeMethod, args);
219
+ };
220
+ cache.set(prop, wrapped);
221
+ return wrapped;
222
+ } });
223
+ }
224
+
225
+ //#endregion
226
+ //#region src/index.ts
8
227
  /**
9
- * @description 当前包版本号
228
+ * @description 默认跨平台 API 实例(推荐使用)
10
229
  */
11
- const VERSION = "0.0.0";
230
+ const wpi = createWeapi();
12
231
 
13
232
  //#endregion
14
- export { VERSION, greet };
233
+ export { createWeapi, wpi };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/api",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.1.0",
5
5
  "description": "tsdown bundler template",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -17,23 +17,27 @@
17
17
  "sideEffects": false,
18
18
  "exports": {
19
19
  ".": {
20
- "types": "./dist/index.d.mts",
20
+ "types": "./types/index.d.ts",
21
21
  "import": {
22
- "types": "./dist/index.d.mts",
22
+ "types": "./types/index.d.ts",
23
23
  "default": "./dist/index.mjs"
24
24
  },
25
25
  "require": {
26
- "types": "./dist/index.d.cts",
26
+ "types": "./types/index.d.ts",
27
27
  "default": "./dist/index.cjs"
28
28
  }
29
29
  }
30
30
  },
31
31
  "main": "./dist/index.cjs",
32
32
  "module": "./dist/index.mjs",
33
- "types": "./dist/index.d.mts",
33
+ "types": "./types/index.d.ts",
34
34
  "files": [
35
- "dist"
35
+ "dist",
36
+ "types"
36
37
  ],
38
+ "dependencies": {
39
+ "miniprogram-api-typings": "^5.0.0"
40
+ },
37
41
  "publishConfig": {
38
42
  "access": "public"
39
43
  },
@@ -42,6 +46,7 @@
42
46
  "build": "tsdown",
43
47
  "test": "vitest run",
44
48
  "test:dev": "vitest",
49
+ "test:types": "tsd",
45
50
  "release": "pnpm publish",
46
51
  "lint": "eslint .",
47
52
  "lint:fix": "eslint . --fix"
@@ -0,0 +1,26 @@
1
+ /// <reference types="miniprogram-api-typings" />
2
+
3
+ // eslint-disable-next-line antfu/no-import-dist
4
+ import type {
5
+ CreateWeapiOptions,
6
+ WeapiAdapter,
7
+ WeapiInstance,
8
+ WeapiPromisify,
9
+ WeapiWxAdapter,
10
+ WeapiWxRawAdapter,
11
+ } from '../dist/index.d.mts'
12
+
13
+ export type {
14
+ CreateWeapiOptions,
15
+ WeapiAdapter,
16
+ WeapiInstance,
17
+ WeapiPromisify,
18
+ WeapiWxAdapter,
19
+ WeapiWxRawAdapter,
20
+ }
21
+
22
+ export function createWeapi<TAdapter extends WeapiAdapter = WeapiWxRawAdapter>(
23
+ options?: CreateWeapiOptions<TAdapter>,
24
+ ): WeapiInstance<TAdapter>
25
+
26
+ export const wpi: WeapiInstance<WechatMiniprogram.Wx>