@hhhpyb/system-assistant-client 1.3.6
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 +86 -0
- package/dist/index.js +87 -0
- package/nuxt.cjs +127 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @hhhpyb/system-assistant-client
|
|
2
|
+
|
|
3
|
+
Nuxt 2 客户端插件:自动加载 [sa-guide-sdk](https://www.npmjs.com/package/sa-guide-sdk) bootstrap,并在路由切换后刷新指引。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hhhpyb/system-assistant-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Nuxt 2 接入
|
|
12
|
+
|
|
13
|
+
### 1. 注册模块
|
|
14
|
+
|
|
15
|
+
`nuxt.config.js`:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
export default {
|
|
19
|
+
modules: [
|
|
20
|
+
'@hhhpyb/system-assistant-client/nuxt',
|
|
21
|
+
],
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
无需在 `nuxt.config.js` 中配置 `SA_GUIDE_APP_KEY`。模块会在构建时自动将应用标识注入 Nuxt 运行时配置。
|
|
26
|
+
|
|
27
|
+
模块还会自动接入 `@hhhpyb/guide-compiler`:Nuxt 2/Bridge 的 Webpack 与 Vite 客户端构建均会在不重复挂载的前提下生成 `.nuxt/sa-guide-manifest.json`,无需在业务项目中配置 compiler loader 或 Vite plugin。
|
|
28
|
+
|
|
29
|
+
### 应用标识推导
|
|
30
|
+
|
|
31
|
+
`SA_GUIDE_APP_KEY` 按以下优先级确定:
|
|
32
|
+
|
|
33
|
+
1. `nuxt.config.js` 中已显式配置的 `env.SA_GUIDE_APP_KEY`;
|
|
34
|
+
2. 构建环境变量 `SA_GUIDE_APP_KEY`;
|
|
35
|
+
3. 业务项目根目录 `package.json` 的 `name`;
|
|
36
|
+
4. 项目根目录名(构建时会输出明确警告)。
|
|
37
|
+
|
|
38
|
+
包名会规范化为安全短标识:npm scope 会被移除,例如 `@company/ehr` 会得到 `ehr`。不会根据域名推导应用标识。
|
|
39
|
+
|
|
40
|
+
### 可选配置
|
|
41
|
+
|
|
42
|
+
仅在需要覆盖默认 API 或 Studio 管理后台 origin 时,在 `nuxt.config.js` 中配置:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
export default {
|
|
46
|
+
env: {
|
|
47
|
+
SA_GUIDE_API_BASE: process.env.SA_GUIDE_API_BASE || 'http://127.0.0.1:8000',
|
|
48
|
+
SA_GUIDE_EDITOR_PARENT_ORIGIN: process.env.SA_GUIDE_EDITOR_PARENT_ORIGIN || '*',
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| 变量 | 说明 | 默认值 |
|
|
54
|
+
|------|------|--------|
|
|
55
|
+
| `SA_GUIDE_API_BASE` | 指引 API 根地址(可不含 `/system-assistant` 后缀) | `http://127.0.0.1:8000` |
|
|
56
|
+
| `SA_GUIDE_APP_KEY` | 可选的应用标识覆盖值 | 自动推导 |
|
|
57
|
+
| `SA_GUIDE_EDITOR_PARENT_ORIGIN` | Studio 配置态管理后台 origin | `*` |
|
|
58
|
+
|
|
59
|
+
### Studio 配置态
|
|
60
|
+
|
|
61
|
+
URL 带 `?sa_studio=1` 时自动进入 Studio 点选模式,支持 `sa_app_key`、`sa_api`、`sa_origin` 查询参数覆盖。
|
|
62
|
+
|
|
63
|
+
## 行为说明
|
|
64
|
+
|
|
65
|
+
- 仅客户端执行(`process.server` 时跳过)
|
|
66
|
+
- 从 `{apiBase}/sdk/v1/bootstrap.js` 加载 SDK
|
|
67
|
+
- 普通模式:调用 `SystemAssistantBootstrap.start()`
|
|
68
|
+
- 路由 `afterEach` 后自动调用 `SystemAssistant.checkAllContexts()` 刷新指引
|
|
69
|
+
|
|
70
|
+
## 发布(维护者)
|
|
71
|
+
|
|
72
|
+
源码:`system-assistant/deployables/sa-guide-sdk/app/v1/system-assistant.client.js`
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd packages/system-assistant-client
|
|
76
|
+
|
|
77
|
+
# 1. 更新 sa-guide-sdk/app/v1/system-assistant.client.js 中的 SA_GUIDE_ASSET_VERSION
|
|
78
|
+
# 2. 同步 package.json version
|
|
79
|
+
npm run build
|
|
80
|
+
npm login
|
|
81
|
+
npm publish --access public --registry=<npm-registry>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 许可证
|
|
85
|
+
|
|
86
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const DEFAULT_API_BASE = 'http://127.0.0.1:8000';
|
|
2
|
+
const DEFAULT_APP_KEY = 'ehr';
|
|
3
|
+
const SA_GUIDE_ASSET_VERSION = '1.3.9';
|
|
4
|
+
|
|
5
|
+
function normalizeApiBase(apiBase) {
|
|
6
|
+
const raw = (apiBase || DEFAULT_API_BASE).replace(/\/$/, '');
|
|
7
|
+
return raw.endsWith('/system-assistant') ? raw : `${raw}/system-assistant`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isStudioMode() {
|
|
11
|
+
const params = new URLSearchParams(window.location.search);
|
|
12
|
+
return params.get('sa_studio') === '1' || params.get('sa_studio') === 'true';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function loadBootstrap(apiBase) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
if (window.SystemAssistantBootstrap) {
|
|
18
|
+
resolve(window.SystemAssistantBootstrap);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const existing = document.querySelector('script[data-sa-guide-bootstrap="1"]');
|
|
23
|
+
if (existing) {
|
|
24
|
+
existing.addEventListener('load', () => resolve(window.SystemAssistantBootstrap));
|
|
25
|
+
existing.addEventListener('error', reject);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const script = document.createElement('script');
|
|
30
|
+
script.src = `${apiBase}/sdk/v1/bootstrap.js?v=${SA_GUIDE_ASSET_VERSION}`;
|
|
31
|
+
script.async = true;
|
|
32
|
+
script.dataset.saGuideBootstrap = '1';
|
|
33
|
+
script.onload = () => resolve(window.SystemAssistantBootstrap);
|
|
34
|
+
script.onerror = reject;
|
|
35
|
+
document.head.appendChild(script);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default async function systemAssistantPlugin({ app, $config }) {
|
|
40
|
+
if (process.server) return;
|
|
41
|
+
|
|
42
|
+
const apiBase = normalizeApiBase($config && $config.SA_GUIDE_API_BASE);
|
|
43
|
+
const appKey = ($config && $config.SA_GUIDE_APP_KEY) || DEFAULT_APP_KEY;
|
|
44
|
+
const editorParentOrigin = ($config && $config.SA_GUIDE_EDITOR_PARENT_ORIGIN) || '*';
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
window.SA_APP_KEY = appKey;
|
|
48
|
+
window.SA_WATCH_IFRAME = true;
|
|
49
|
+
|
|
50
|
+
const bootstrap = await loadBootstrap(apiBase);
|
|
51
|
+
|
|
52
|
+
const startStudio = async () => {
|
|
53
|
+
if (!isStudioMode()) return;
|
|
54
|
+
const params = new URLSearchParams(window.location.search);
|
|
55
|
+
const sdk = await bootstrap.loadSdk();
|
|
56
|
+
await sdk.startStudio({
|
|
57
|
+
appKey: params.get('sa_app_key') || appKey,
|
|
58
|
+
apiBase: params.get('sa_api') || apiBase,
|
|
59
|
+
adminOrigin: params.get('sa_origin') || editorParentOrigin,
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (isStudioMode()) {
|
|
64
|
+
await startStudio();
|
|
65
|
+
} else {
|
|
66
|
+
await bootstrap.start({
|
|
67
|
+
appKey,
|
|
68
|
+
apiBase,
|
|
69
|
+
watchIframe: true,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (app.router) {
|
|
74
|
+
app.router.afterEach(() => {
|
|
75
|
+
window.setTimeout(() => {
|
|
76
|
+
if (isStudioMode()) {
|
|
77
|
+
startStudio();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
window.SystemAssistant && window.SystemAssistant.checkAllContexts && window.SystemAssistant.checkAllContexts();
|
|
81
|
+
}, 300);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.warn('[SystemAssistant] SDK load failed', error);
|
|
86
|
+
}
|
|
87
|
+
}
|
package/nuxt.cjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const { resolve } = require('node:path')
|
|
2
|
+
const { readFileSync } = require('node:fs')
|
|
3
|
+
const setupGuideCompilerNuxt2 = require('@hhhpyb/guide-compiler/nuxt2')
|
|
4
|
+
|
|
5
|
+
const APP_KEY_ENV = 'SA_GUIDE_APP_KEY'
|
|
6
|
+
const GUIDE_COMPILER_WEBPACK_MARKER = Symbol.for('system-assistant.guide-compiler.webpack')
|
|
7
|
+
const GUIDE_COMPILER_VITE_MARKER = Symbol.for('system-assistant.guide-compiler.vite')
|
|
8
|
+
|
|
9
|
+
function normalizeAppKey(value) {
|
|
10
|
+
if (typeof value !== 'string') return ''
|
|
11
|
+
|
|
12
|
+
const packageName = value.trim().replace(/^@[^/]+\//, '')
|
|
13
|
+
return packageName
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
16
|
+
.replace(/^-+|-+$/g, '')
|
|
17
|
+
.slice(0, 64)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readProvidedAppKey(value) {
|
|
21
|
+
return typeof value === 'string' ? value.trim() : ''
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readPackageName(rootDir) {
|
|
25
|
+
try {
|
|
26
|
+
const packageJson = JSON.parse(readFileSync(resolve(rootDir, 'package.json'), 'utf8'))
|
|
27
|
+
return normalizeAppKey(packageJson.name)
|
|
28
|
+
} catch (_error) {
|
|
29
|
+
return ''
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function resolveAppKey({ configuredAppKey, environmentAppKey, rootDir }) {
|
|
34
|
+
const explicitAppKey = readProvidedAppKey(configuredAppKey)
|
|
35
|
+
if (explicitAppKey) return { appKey: explicitAppKey, source: 'configured' }
|
|
36
|
+
|
|
37
|
+
const envAppKey = readProvidedAppKey(environmentAppKey)
|
|
38
|
+
if (envAppKey) return { appKey: envAppKey, source: 'environment' }
|
|
39
|
+
|
|
40
|
+
const packageAppKey = readPackageName(rootDir)
|
|
41
|
+
if (packageAppKey) return { appKey: packageAppKey, source: 'package' }
|
|
42
|
+
|
|
43
|
+
return { appKey: normalizeAppKey(rootDir.split(/[\\/]/).filter(Boolean).pop()) || 'app', source: 'directory' }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function createGuideCompilerOptions(rootDir, appKey) {
|
|
47
|
+
return {
|
|
48
|
+
enabled: true,
|
|
49
|
+
appKey,
|
|
50
|
+
idPrefix: appKey,
|
|
51
|
+
rootDir,
|
|
52
|
+
include: ['pages', 'components', 'layouts'],
|
|
53
|
+
exclude: ['node_modules', '.nuxt', '.output'],
|
|
54
|
+
manifestOutput: resolve(rootDir, '.nuxt/sa-guide-manifest.json'),
|
|
55
|
+
manifestAsset: 'sa-guide-manifest.json',
|
|
56
|
+
productionDuplicatePolicy: 'block_manual',
|
|
57
|
+
sensitiveWords: ['薪资', '工资', '金额', '审批结论', '身份证', '手机号'],
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function installGuideCompilerWebpack(config, options) {
|
|
62
|
+
if (!config || config[GUIDE_COMPILER_WEBPACK_MARKER]) return config
|
|
63
|
+
setupGuideCompilerNuxt2(config, options)
|
|
64
|
+
Object.defineProperty(config, GUIDE_COMPILER_WEBPACK_MARKER, { value: true })
|
|
65
|
+
return config
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function installGuideCompilerVite(config, options) {
|
|
69
|
+
if (!config || config[GUIDE_COMPILER_VITE_MARKER]) return config
|
|
70
|
+
const { systemAssistantGuideVitePlugin } = await import('@hhhpyb/guide-compiler/vite')
|
|
71
|
+
config.plugins = config.plugins || []
|
|
72
|
+
if (!config.plugins.some((plugin) => plugin && plugin.name === 'system-assistant-guide-compiler')) {
|
|
73
|
+
config.plugins.push(systemAssistantGuideVitePlugin(options))
|
|
74
|
+
}
|
|
75
|
+
Object.defineProperty(config, GUIDE_COMPILER_VITE_MARKER, { value: true })
|
|
76
|
+
return config
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = function systemAssistantClientModule() {
|
|
80
|
+
const rootDir = this.options.rootDir || process.cwd()
|
|
81
|
+
const env = this.options.env || (this.options.env = {})
|
|
82
|
+
const result = resolveAppKey({
|
|
83
|
+
configuredAppKey: env[APP_KEY_ENV],
|
|
84
|
+
environmentAppKey: process.env[APP_KEY_ENV],
|
|
85
|
+
rootDir,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
env[APP_KEY_ENV] = result.appKey
|
|
89
|
+
const guideCompilerOptions = createGuideCompilerOptions(rootDir, result.appKey)
|
|
90
|
+
|
|
91
|
+
if (this.nuxt && typeof this.nuxt.hook === 'function') {
|
|
92
|
+
this.nuxt.hook('webpack:config', (config) => {
|
|
93
|
+
installGuideCompilerWebpack(config, guideCompilerOptions)
|
|
94
|
+
})
|
|
95
|
+
this.nuxt.hook('vite:extendConfig', async (config, context) => {
|
|
96
|
+
if (!context || context.isClient !== true) return
|
|
97
|
+
await installGuideCompilerVite(config, guideCompilerOptions)
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (result.source === 'directory') {
|
|
102
|
+
// Nuxt builds can still proceed when a project omits package.json.name, but
|
|
103
|
+
// the derived key is less stable than a package name and must be visible.
|
|
104
|
+
// eslint-disable-next-line no-console
|
|
105
|
+
console.warn(`[system-assistant-client] package.json name is unavailable; using directory name as SA_GUIDE_APP_KEY: ${result.appKey}`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.addPlugin({
|
|
109
|
+
src: resolve(__dirname, 'dist/index.js'),
|
|
110
|
+
fileName: 'system-assistant.client.js',
|
|
111
|
+
mode: 'client',
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports.meta = {
|
|
116
|
+
name: '@hhhpyb/system-assistant-client',
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports._internal = {
|
|
120
|
+
normalizeAppKey,
|
|
121
|
+
readProvidedAppKey,
|
|
122
|
+
readPackageName,
|
|
123
|
+
resolveAppKey,
|
|
124
|
+
createGuideCompilerOptions,
|
|
125
|
+
installGuideCompilerWebpack,
|
|
126
|
+
installGuideCompilerVite,
|
|
127
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hhhpyb/system-assistant-client",
|
|
3
|
+
"version": "1.3.6",
|
|
4
|
+
"description": "Nuxt 2 client plugin for System Assistant smart guide SDK",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nuxt",
|
|
7
|
+
"nuxt2",
|
|
8
|
+
"guide",
|
|
9
|
+
"system-assistant",
|
|
10
|
+
"plugin"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "http://git.ymdd.tech/twg195158/smart-guide-assistant.git",
|
|
17
|
+
"directory": "system-assistant-front/packages/system-assistant-client"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md",
|
|
22
|
+
"nuxt.cjs"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.js",
|
|
26
|
+
"./nuxt": "./nuxt.cjs"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"nuxt": "^2.0.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependenciesMeta": {
|
|
32
|
+
"nuxt": {
|
|
33
|
+
"optional": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@hhhpyb/guide-compiler": "0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "node scripts/copy-dist.js",
|
|
41
|
+
"test": "node --test test/nuxt.test.cjs",
|
|
42
|
+
"prepublishOnly": "npm run build"
|
|
43
|
+
}
|
|
44
|
+
}
|