@wangnanshan/dsh-nanshan-publish-manager 1.0.2 → 1.0.4
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 +4 -4
- package/client.js +34 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ DSH 组件就是一个 npm 包:
|
|
|
84
84
|
1. **版本与标签** —— 目标版本(写回 `package.json`)、npm tag、`public` / `restricted`。
|
|
85
85
|
2. **发布目标与选项** —— registry(默认读取你的 `~/.npmrc`)、可选构建脚本(`npm run <script>`)、自动运行发布预检查、先演练、自动写入版本号、发布备注。
|
|
86
86
|
3. **发布预检查** —— 运行发布预检查;有阻断项时正式发布按钮不可用。
|
|
87
|
-
4. **确认与执行** —— 选择发布验证方式,勾选确认,先「仅演练」(`npm publish --dry-run
|
|
87
|
+
4. **确认与执行** —— 选择发布验证方式,勾选确认,先「仅演练」(`npm publish --dry-run`,临时写入的目标版本会在演练后还原)或「正式发布」(带最终确认弹窗);本机会话方式的最终弹窗按钮为:左侧「再想想」,右侧「采用终端发布(推荐)」和「采用 OTP 发布」。
|
|
88
88
|
5. **发布记录** —— 每次演练 / 发布 / 失败都会写入本机记录,包含版本、tag、access、验证方式、耗时、预检查摘要和命令输出;终端发布会在记录里标记「终端」。
|
|
89
89
|
|
|
90
90
|
## 发布验证方式
|
|
@@ -101,13 +101,13 @@ npm 已在 **2025-12-09 永久撤销全部经典 Token**,本插件不再提供
|
|
|
101
101
|
|
|
102
102
|
Granular Access Token 可以在 npm 网站 Settings → Tokens 或 `npm token create` 创建;写令牌最长 90 天,无人值守发布建议开启 Bypass 2FA。
|
|
103
103
|
|
|
104
|
-
页面内的 OTP 只支持 TOTP(身份验证器 6 位数字)。如果账号使用安全密钥 / 网页型 2FA,npm
|
|
104
|
+
页面内的 OTP 只支持 TOTP(身份验证器 6 位数字)。如果账号使用安全密钥 / 网页型 2FA,npm 需要在交互式终端里打开浏览器授权;这种情况下可以直接在确认弹窗点「采用终端发布(推荐)」,或创建一个开启 Bypass 2FA 的 Granular Access Token 后使用「细粒度令牌」方式。
|
|
105
105
|
|
|
106
106
|
npm 凭据**不经过插件的存储层**:本机会话使用你自己的 `~/.npmrc`;Granular Token 的临时 npmrc 在发布后删除;OTP 只作用于一次子进程。三者都不会写入发布记录。
|
|
107
107
|
|
|
108
108
|
### 在系统终端发布
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
在「本机登录会话」方式下,最终确认弹窗提供「采用终端发布(推荐)」:
|
|
111
111
|
|
|
112
112
|
- macOS 打开 Terminal.app;
|
|
113
113
|
- Windows 打开 `cmd.exe`;
|
|
@@ -149,7 +149,7 @@ OTP 不是插件强制每次都要填写的字段:
|
|
|
149
149
|
|
|
150
150
|
1. 确认验证码来自**当前登录账号**(`npm whoami` 显示 `wangnanshan`)绑定的身份验证器,并且是刚生成的;旧码不能复用。
|
|
151
151
|
2. 确认系统时间自动同步。TOTP 依赖本机时钟;当前机器与 npm registry 的偏差约 0.6 秒,属于正常范围。
|
|
152
|
-
3. 如果账号的 2FA 方式是**安全密钥 / 网页认证**而不是身份验证器 TOTP,页面内输入 6
|
|
152
|
+
3. 如果账号的 2FA 方式是**安全密钥 / 网页认证**而不是身份验证器 TOTP,页面内输入 6 位码不会成功。请在确认弹窗点「采用终端发布(推荐)」,让 npm 在系统终端里打开浏览器授权;或使用下面的令牌方案。
|
|
153
153
|
4. 使用 **Granular Access Token** 时,必须在创建令牌时勾选 **Bypass 2FA**(`npm token create --bypass-2fa`);只粘贴一个未开启 Bypass 2FA 的令牌仍会返回 EOTP。
|
|
154
154
|
5. 如果配置了构建脚本,构建会先于发布执行;构建较慢时验证码可能过期,建议使用开启 Bypass 2FA 的令牌。
|
|
155
155
|
|
package/client.js
CHANGED
|
@@ -29,7 +29,8 @@ window.__ModuleLoader__.load({
|
|
|
29
29
|
'action.dryRun': '仅演练',
|
|
30
30
|
'action.dryRunning': '演练中…',
|
|
31
31
|
'action.publish': '正式发布',
|
|
32
|
-
'action.publishTerminal': '
|
|
32
|
+
'action.publishTerminal': '采用终端发布(推荐)',
|
|
33
|
+
'action.reconsider': '再想想',
|
|
33
34
|
'action.terminalWaiting': '等待终端…',
|
|
34
35
|
'action.publishing': '发布中…',
|
|
35
36
|
'action.cancel': '再想想',
|
|
@@ -241,8 +242,9 @@ window.__ModuleLoader__.load({
|
|
|
241
242
|
'modal.publishWarning': '请确认版本号、tag 与可见范围都正确;公开包会立刻被其他人安装到。',
|
|
242
243
|
'modal.dryFirstHint': '本次设置启用了「发布前先演练」,你还没有在本次会话里演练;确认后仍会直接正式发布。',
|
|
243
244
|
'modal.publishOk': '确认发布',
|
|
245
|
+
'modal.otpPublish': '采用 OTP 发布',
|
|
244
246
|
'modal.otpHint': '请填写刚生成的验证码;一次性、约 30 秒有效。',
|
|
245
|
-
'modal.terminalHint': '
|
|
247
|
+
'modal.terminalHint': '推荐用系统终端发布:npm 会在终端里询问 OTP 或打开浏览器完成 2FA,插件等待结果并写入记录。也可以填写上方 OTP,改用「采用 OTP 发布」。',
|
|
246
248
|
'modal.buildBeforeOtp': '当前配置了构建脚本:发布前会先执行构建,耗时较长时验证码可能过期;建议使用开启 Bypass 2FA 的 Granular Token。',
|
|
247
249
|
'toast.settingsSaved': '发布设置已保存',
|
|
248
250
|
'toast.checkDone': '预检查完成',
|
|
@@ -354,7 +356,8 @@ window.__ModuleLoader__.load({
|
|
|
354
356
|
'action.dryRun': 'Dry run',
|
|
355
357
|
'action.dryRunning': 'Dry running…',
|
|
356
358
|
'action.publish': 'Publish',
|
|
357
|
-
'action.publishTerminal': 'Publish in terminal',
|
|
359
|
+
'action.publishTerminal': 'Publish in terminal (recommended)',
|
|
360
|
+
'action.reconsider': 'Reconsider',
|
|
358
361
|
'action.terminalWaiting': 'Waiting for terminal…',
|
|
359
362
|
'action.publishing': 'Publishing…',
|
|
360
363
|
'action.cancel': 'Not yet',
|
|
@@ -566,8 +569,9 @@ window.__ModuleLoader__.load({
|
|
|
566
569
|
'modal.publishWarning': 'Double-check the version, tag, and access. A public package becomes installable immediately.',
|
|
567
570
|
'modal.dryFirstHint': '“Dry run first” is enabled but no dry run has happened in this session; confirming publishes directly.',
|
|
568
571
|
'modal.publishOk': 'Publish',
|
|
572
|
+
'modal.otpPublish': 'Publish with OTP',
|
|
569
573
|
'modal.otpHint': 'Enter a freshly generated code; single-use and valid for about 30 seconds.',
|
|
570
|
-
'modal.terminalHint': '
|
|
574
|
+
'modal.terminalHint': 'Recommended: publish in the system terminal. npm handles OTP or web 2FA there, and the plugin records the result. You can also enter an OTP above and use “Publish with OTP”.',
|
|
571
575
|
'modal.buildBeforeOtp': 'A build script is configured: the build runs before publishing and may outlast the OTP; a Granular Access Token with Bypass 2FA is recommended.',
|
|
572
576
|
'toast.settingsSaved': 'Release settings saved',
|
|
573
577
|
'toast.checkDone': 'Pre-check finished',
|
|
@@ -879,6 +883,8 @@ window.__ModuleLoader__.load({
|
|
|
879
883
|
.np-dialog .np-field{margin:2px 0 10px}
|
|
880
884
|
.np-dialog__warn{padding:8px 10px;border:1px solid color-mix(in srgb,var(--np-bad) 30%,var(--np-line));border-radius:8px;background:color-mix(in srgb,var(--np-bad) 6%,transparent);color:var(--np-bad)!important}
|
|
881
885
|
.np-dialog__actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}
|
|
886
|
+
.np-dialog__actions--split{justify-content:space-between;flex-wrap:wrap}
|
|
887
|
+
.np-dialog__actions-right{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap;margin-left:auto}
|
|
882
888
|
.np-dialog.np-dialog--info{width:min(560px,100%)}
|
|
883
889
|
.np-dialog.np-dialog--error{width:min(540px,100%)}
|
|
884
890
|
.np-dialog--error .np-info__head h2{margin:0;flex:1;min-width:0}
|
|
@@ -2528,23 +2534,32 @@ window.__ModuleLoader__.load({
|
|
|
2528
2534
|
settings.dryRunFirst && !records.some((record) => record.dryRun === true)
|
|
2529
2535
|
? h('p', { className: 'np-hint' }, t('modal.dryFirstHint'))
|
|
2530
2536
|
: null,
|
|
2531
|
-
h('div', { className: 'np-dialog__actions' },
|
|
2532
|
-
authMode === 'session'
|
|
2533
|
-
? h('button', {
|
|
2534
|
-
type: 'button',
|
|
2535
|
-
className: 'np-btn',
|
|
2536
|
-
disabled: busy !== '' || blocked !== '',
|
|
2537
|
-
onClick: publishInTerminal,
|
|
2538
|
-
}, h(Glyph, { name: 'terminal', size: 13 }), busy === 'terminal' ? t('action.terminalWaiting') : t('action.publishTerminal'))
|
|
2539
|
-
: null,
|
|
2540
|
-
h('button', { type: 'button', className: 'np-btn np-btn--ghost', onClick: () => setModalOpen(false) }, t('action.cancel')),
|
|
2537
|
+
h('div', { className: 'np-dialog__actions np-dialog__actions--split' },
|
|
2541
2538
|
h('button', {
|
|
2542
2539
|
type: 'button',
|
|
2543
|
-
className: 'np-btn np-btn--
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2540
|
+
className: 'np-btn np-btn--ghost',
|
|
2541
|
+
onClick: () => setModalOpen(false),
|
|
2542
|
+
}, t('action.reconsider')),
|
|
2543
|
+
h('div', { className: 'np-dialog__actions-right' },
|
|
2544
|
+
authMode === 'session'
|
|
2545
|
+
? h('button', {
|
|
2546
|
+
type: 'button',
|
|
2547
|
+
className: 'np-btn np-btn--primary',
|
|
2548
|
+
disabled: busy !== '' || blocked !== '',
|
|
2549
|
+
onClick: publishInTerminal,
|
|
2550
|
+
}, h(Glyph, { name: 'terminal', size: 13 }), busy === 'terminal' ? t('action.terminalWaiting') : t('action.publishTerminal'))
|
|
2551
|
+
: null,
|
|
2552
|
+
h('button', {
|
|
2553
|
+
type: 'button',
|
|
2554
|
+
className: authMode === 'session' ? 'np-btn' : 'np-btn np-btn--primary',
|
|
2555
|
+
ref: okButtonRef,
|
|
2556
|
+
disabled: busy !== '' || blocked !== '',
|
|
2557
|
+
onClick: () => publish(false),
|
|
2558
|
+
},
|
|
2559
|
+
authMode === 'session' ? h(Glyph, { name: 'upload', size: 13 }) : null,
|
|
2560
|
+
authMode === 'session' ? t('modal.otpPublish') : t('modal.publishOk'),
|
|
2561
|
+
),
|
|
2562
|
+
),
|
|
2548
2563
|
),
|
|
2549
2564
|
),
|
|
2550
2565
|
)
|
package/package.json
CHANGED