@syfei49/mini-dynamic-renderer 1.0.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.
Potentially problematic release.
This version of @syfei49/mini-dynamic-renderer might be problematic. Click here for more details.
- package/README.md +102 -0
- package/index.js +14 -0
- package/package.json +18 -0
- package/src/handler.js +49 -0
- package/src/init.js +57 -0
- package/src/interceptor.js +104 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @syfei49/mini-dynamic-renderer
|
|
2
|
+
|
|
3
|
+
微信小程序对话接口动态渲染 SDK(v1.0.0 测试版)。
|
|
4
|
+
|
|
5
|
+
引入后自动注册 `wx.request` 拦截器;当匹配的接口返回成功(`statusCode === 200`)时,在当前页面弹出 `hello world` 测试弹窗。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd your-miniprogram-project
|
|
11
|
+
npm install @syfei49/mini-dynamic-renderer
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 接入
|
|
15
|
+
|
|
16
|
+
### 1. 在 `app.js` 顶部引入(自动注册拦截器)
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
require('@syfei49/mini-dynamic-renderer');
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. 微信开发者工具构建 npm
|
|
23
|
+
|
|
24
|
+
打开微信开发者工具 → **工具** → **构建 npm**
|
|
25
|
+
|
|
26
|
+
### 3. 正常发起请求即可触发弹窗
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
wx.request({
|
|
30
|
+
url: 'https://your-domain.com/api/chat',
|
|
31
|
+
method: 'POST',
|
|
32
|
+
data: { query: '你好' },
|
|
33
|
+
success(res) {
|
|
34
|
+
// 原有业务逻辑不变
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 配置(可选)
|
|
40
|
+
|
|
41
|
+
如需自定义拦截规则,可在 `app.js` 中显式初始化:
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const sdk = require('@syfei49/mini-dynamic-renderer');
|
|
45
|
+
|
|
46
|
+
sdk.init({
|
|
47
|
+
// URL 匹配规则:字符串为包含匹配,也支持 RegExp,'*' 表示全部
|
|
48
|
+
urlPatterns: ['/api/chat'],
|
|
49
|
+
debug: true
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 配置项
|
|
54
|
+
|
|
55
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
56
|
+
|------|------|--------|------|
|
|
57
|
+
| `urlPatterns` | `Array<string\|RegExp>` | `['*']` | 需要拦截的 URL 规则 |
|
|
58
|
+
| `debug` | `boolean` | `false` | 是否输出调试日志 |
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
| 方法 | 说明 |
|
|
63
|
+
|------|------|
|
|
64
|
+
| `init(config?)` | 初始化并注册拦截器 |
|
|
65
|
+
| `getConfig()` | 获取当前配置 |
|
|
66
|
+
| `isInitialized()` | 是否已初始化 |
|
|
67
|
+
| `uninstall()` | 卸载拦截器,恢复原始 `wx.request` |
|
|
68
|
+
| `parseRenderConfig(data)` | 解析响应中的渲染配置(预留) |
|
|
69
|
+
|
|
70
|
+
## 发布到 npm
|
|
71
|
+
|
|
72
|
+
在包根目录 `code/` 下执行:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 1. 确认已登录
|
|
76
|
+
npm whoami
|
|
77
|
+
|
|
78
|
+
# 2. 确认 registry
|
|
79
|
+
npm config get registry
|
|
80
|
+
# 应为 https://registry.npmjs.org/
|
|
81
|
+
|
|
82
|
+
# 3. 检查包名是否可用(404 表示可用)
|
|
83
|
+
npm view @syfei49/mini-dynamic-renderer
|
|
84
|
+
|
|
85
|
+
# 4. 预览将要发布的文件
|
|
86
|
+
npm pack --dry-run
|
|
87
|
+
|
|
88
|
+
# 5. 正式发布(作用域包首次需 public)
|
|
89
|
+
npm publish --access public
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
后续版本更新:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm version patch # 或 minor / major
|
|
96
|
+
npm publish --access public
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 版本说明
|
|
100
|
+
|
|
101
|
+
- **v1.0.0**:拦截 `wx.request` 成功响应,弹出 `hello world` 测试弹窗
|
|
102
|
+
- 后续版本将支持根据后端 `renderConfig` 动态渲染图片上传、文本等组件
|
package/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
var initModule = require('./src/init');
|
|
2
|
+
var interceptor = require('./src/interceptor');
|
|
3
|
+
var handler = require('./src/handler');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
init: initModule.init,
|
|
8
|
+
getConfig: initModule.getConfig,
|
|
9
|
+
isInitialized: initModule.isInitialized,
|
|
10
|
+
uninstall: interceptor.uninstallInterceptor,
|
|
11
|
+
parseRenderConfig: handler.parseRenderConfig
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
initModule.init();
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@syfei49/mini-dynamic-renderer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "微信小程序对话接口动态渲染 SDK",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"miniprogram": ".",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js",
|
|
9
|
+
"src"
|
|
10
|
+
],
|
|
11
|
+
"keywords": [
|
|
12
|
+
"wechat",
|
|
13
|
+
"miniprogram",
|
|
14
|
+
"dynamic-renderer"
|
|
15
|
+
],
|
|
16
|
+
"author": "syfei49",
|
|
17
|
+
"license": "MIT"
|
|
18
|
+
}
|
package/src/handler.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 从响应数据中解析渲染配置(预留,供后续版本使用)
|
|
3
|
+
* @param {*} data - 接口返回的 data 字段
|
|
4
|
+
* @returns {Object|null}
|
|
5
|
+
*/
|
|
6
|
+
function parseRenderConfig(data) {
|
|
7
|
+
if (!data || typeof data !== 'object') {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (data.renderConfig && typeof data.renderConfig === 'object') {
|
|
12
|
+
return data.renderConfig;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (data.type) {
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* v1.0.0: 拦截成功后弹出 hello world 测试弹窗
|
|
24
|
+
* @param {Object} res - wx.request success 回调的响应对象
|
|
25
|
+
* @param {Object} requestOptions - 原始 wx.request 入参
|
|
26
|
+
* @param {Object} config - SDK 配置
|
|
27
|
+
*/
|
|
28
|
+
function handleResponse(res, requestOptions, config) {
|
|
29
|
+
var renderConfig = parseRenderConfig(res.data);
|
|
30
|
+
|
|
31
|
+
if (config.debug) {
|
|
32
|
+
console.log('[mini-dynamic-renderer] intercepted:', requestOptions.url, res.data);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
wx.showModal({
|
|
36
|
+
title: 'mini-dynamic-renderer',
|
|
37
|
+
content: 'hello world',
|
|
38
|
+
showCancel: false
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (renderConfig && config.debug) {
|
|
42
|
+
console.log('[mini-dynamic-renderer] renderConfig:', renderConfig);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
parseRenderConfig: parseRenderConfig,
|
|
48
|
+
handleResponse: handleResponse
|
|
49
|
+
};
|
package/src/init.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var interceptor = require('./interceptor');
|
|
2
|
+
|
|
3
|
+
var currentConfig = null;
|
|
4
|
+
var initialized = false;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 合并用户配置与默认配置
|
|
8
|
+
* @param {Object} userConfig
|
|
9
|
+
* @returns {Object}
|
|
10
|
+
*/
|
|
11
|
+
function mergeConfig(userConfig) {
|
|
12
|
+
var base = interceptor.DEFAULT_CONFIG;
|
|
13
|
+
var config = userConfig || {};
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
urlPatterns: config.urlPatterns || base.urlPatterns,
|
|
17
|
+
debug: typeof config.debug === 'boolean' ? config.debug : base.debug
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 初始化 SDK,注册 wx.request 拦截器
|
|
23
|
+
* @param {Object} [userConfig]
|
|
24
|
+
* @param {Array<string|RegExp>} [userConfig.urlPatterns] - URL 匹配规则,默认 ['*'] 匹配全部
|
|
25
|
+
* @param {boolean} [userConfig.debug] - 是否输出调试日志
|
|
26
|
+
* @returns {Object} 当前配置
|
|
27
|
+
*/
|
|
28
|
+
function init(userConfig) {
|
|
29
|
+
if (initialized && !userConfig) {
|
|
30
|
+
return currentConfig;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (initialized && userConfig) {
|
|
34
|
+
interceptor.uninstallInterceptor();
|
|
35
|
+
initialized = false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
currentConfig = mergeConfig(userConfig);
|
|
39
|
+
interceptor.installInterceptor(currentConfig);
|
|
40
|
+
initialized = true;
|
|
41
|
+
|
|
42
|
+
if (currentConfig.debug) {
|
|
43
|
+
console.log('[mini-dynamic-renderer] initialized', currentConfig);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return currentConfig;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
init: init,
|
|
51
|
+
getConfig: function () {
|
|
52
|
+
return currentConfig;
|
|
53
|
+
},
|
|
54
|
+
isInitialized: function () {
|
|
55
|
+
return initialized;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var handler = require('./handler');
|
|
2
|
+
|
|
3
|
+
var originalRequest = null;
|
|
4
|
+
var installed = false;
|
|
5
|
+
|
|
6
|
+
var DEFAULT_CONFIG = {
|
|
7
|
+
urlPatterns: ['*'],
|
|
8
|
+
debug: false
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 判断 URL 是否匹配配置的模式
|
|
13
|
+
* @param {string} url
|
|
14
|
+
* @param {Array<string|RegExp>} patterns
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
function matchUrl(url, patterns) {
|
|
18
|
+
if (!patterns || patterns.length === 0) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
for (var i = 0; i < patterns.length; i++) {
|
|
23
|
+
var pattern = patterns[i];
|
|
24
|
+
|
|
25
|
+
if (pattern === '*') {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (pattern instanceof RegExp) {
|
|
30
|
+
if (pattern.test(url)) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof pattern === 'string' && url.indexOf(pattern) !== -1) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 安装 wx.request 拦截器
|
|
46
|
+
* @param {Object} config
|
|
47
|
+
*/
|
|
48
|
+
function installInterceptor(config) {
|
|
49
|
+
if (installed) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (typeof wx === 'undefined' || typeof wx.request !== 'function') {
|
|
54
|
+
console.warn('[mini-dynamic-renderer] wx.request is not available, skip interceptor install');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
originalRequest = wx.request;
|
|
59
|
+
installed = true;
|
|
60
|
+
|
|
61
|
+
wx.request = function (options) {
|
|
62
|
+
var userSuccess = options.success;
|
|
63
|
+
var mergedConfig = config || DEFAULT_CONFIG;
|
|
64
|
+
|
|
65
|
+
options.success = function (res) {
|
|
66
|
+
if (res && res.statusCode === 200 && matchUrl(options.url || '', mergedConfig.urlPatterns)) {
|
|
67
|
+
try {
|
|
68
|
+
handler.handleResponse(res, options, mergedConfig);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error('[mini-dynamic-renderer] handleResponse error:', err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (typeof userSuccess === 'function') {
|
|
75
|
+
userSuccess(res);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return originalRequest.call(wx, options);
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 卸载拦截器,恢复原始 wx.request
|
|
85
|
+
*/
|
|
86
|
+
function uninstallInterceptor() {
|
|
87
|
+
if (!installed || !originalRequest) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
wx.request = originalRequest;
|
|
92
|
+
originalRequest = null;
|
|
93
|
+
installed = false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
DEFAULT_CONFIG: DEFAULT_CONFIG,
|
|
98
|
+
matchUrl: matchUrl,
|
|
99
|
+
installInterceptor: installInterceptor,
|
|
100
|
+
uninstallInterceptor: uninstallInterceptor,
|
|
101
|
+
isInstalled: function () {
|
|
102
|
+
return installed;
|
|
103
|
+
}
|
|
104
|
+
};
|