@alipay/alipay-aipay 1.7.0 → 1.7.2
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 +30 -0
- package/dist/commands/install-current.js +15 -7
- package/dist/commands/install.js +20 -16
- package/dist/commands/uninstall.js +8 -3
- package/dist/commands/update.js +34 -16
- package/dist/index.js +10 -4
- package/dist/utils/channels.js +67 -0
- package/dist/utils/config.js +15 -11
- package/dist/utils/file.js +23 -10
- package/dist/utils/npm.js +19 -33
- package/package.json +8 -3
- package/skill/SKILL.md +2 -0
- package/skill/references/normal/json/release-channel.json +1 -0
- package/skill/references/normal/scripts/self_update.mjs +62 -17
- package/skill/references/normal/self-update.md +3 -1
- package/skill-pre/SKILL.md +65 -0
- package/skill-pre/VERSION +1 -0
- package/skill-pre/references/integration/flow.md +602 -0
- package/skill-pre/references/integration/modules/alipay-sdk-reminder.md +281 -0
- package/skill-pre/references/integration/modules/checklist.md +154 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +199 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +68 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +83 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +80 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +132 -0
- package/skill-pre/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +640 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +184 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +72 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +96 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +81 -0
- package/skill-pre/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
- package/skill-pre/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +69 -0
- package/skill-pre/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +138 -0
- package/skill-pre/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.md +623 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +63 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +54 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +84 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +71 -0
- package/skill-pre/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +498 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +157 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +69 -0
- package/skill-pre/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
- package/skill-pre/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
- package/skill-pre/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +110 -0
- package/skill-pre/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +806 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +70 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
- package/skill-pre/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
- package/skill-pre/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
- package/skill-pre/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +47 -0
- package/skill-pre/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.md +541 -0
- package/skill-pre/references/integration/modules/interface-contract/aipay-interface-contract.md +52 -0
- package/skill-pre/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
- package/skill-pre/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
- package/skill-pre/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
- package/skill-pre/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
- package/skill-pre/references/integration/modules/interface-guide.md +61 -0
- package/skill-pre/references/integration/modules/product-decision.md +73 -0
- package/skill-pre/references/integration/modules/sandbox/a2m-sandbox-test.md +235 -0
- package/skill-pre/references/integration/modules/sandbox/alipay-sandbox-tool.md +142 -0
- package/skill-pre/references/integration/modules/sandbox/sandbox-setup-guide.md +239 -0
- package/skill-pre/references/integration/modules/scripts/local_402_sandbox_pay.py +900 -0
- package/skill-pre/references/integration/modules/scripts/sandbox_config.sh +347 -0
- package/skill-pre/references/integration/modules/troubleshooting-flow.md +28 -0
- package/skill-pre/references/normal/alipay-cli-env.md +169 -0
- package/skill-pre/references/normal/conversation-telemetry.md +101 -0
- package/skill-pre/references/normal/full-process-routing.md +92 -0
- package/skill-pre/references/normal/integration-worker.md +90 -0
- package/skill-pre/references/normal/json/customer-messages.json +1 -0
- package/skill-pre/references/normal/json/managed-jq-assets.json +1 -0
- package/skill-pre/references/normal/json/policy-rules.json +1 -0
- package/skill-pre/references/normal/json/release-channel.json +1 -0
- package/skill-pre/references/normal/rejection-guide.md +41 -0
- package/skill-pre/references/normal/scripts/agent_platform.mjs +43 -0
- package/skill-pre/references/normal/scripts/alipay_cli_env.mjs +34 -0
- package/skill-pre/references/normal/scripts/alipay_cli_env.sh +55 -0
- package/skill-pre/references/normal/scripts/alipay_cli_refresh.mjs +129 -0
- package/skill-pre/references/normal/scripts/auth_runtime_runner.mjs +60 -0
- package/skill-pre/references/normal/scripts/checklist_sections.mjs +43 -0
- package/skill-pre/references/normal/scripts/common.sh +365 -0
- package/skill-pre/references/normal/scripts/conversation_telemetry.mjs +105 -0
- package/skill-pre/references/normal/scripts/detect_dev_tool.sh +79 -0
- package/skill-pre/references/normal/scripts/flow_loader.mjs +237 -0
- package/skill-pre/references/normal/scripts/integration_context_runner.mjs +151 -0
- package/skill-pre/references/normal/scripts/integration_message_runner.mjs +1456 -0
- package/skill-pre/references/normal/scripts/interaction_reply.mjs +140 -0
- package/skill-pre/references/normal/scripts/managed_jq.mjs +215 -0
- package/skill-pre/references/normal/scripts/onboarding_discovery_runner.mjs +387 -0
- package/skill-pre/references/normal/scripts/onboarding_message_runner.mjs +1425 -0
- package/skill-pre/references/normal/scripts/onboarding_recovery_runner.mjs +100 -0
- package/skill-pre/references/normal/scripts/open_official_url.sh +205 -0
- package/skill-pre/references/normal/scripts/platform_compat.mjs +42 -0
- package/skill-pre/references/normal/scripts/preview_runtime.mjs +151 -0
- package/skill-pre/references/normal/scripts/project_route_inspector.sh +132 -0
- package/skill-pre/references/normal/scripts/python_script_runner.mjs +58 -0
- package/skill-pre/references/normal/scripts/render_customer_message.mjs +1792 -0
- package/skill-pre/references/normal/scripts/runtime.mjs +271 -0
- package/skill-pre/references/normal/scripts/self_update.mjs +376 -0
- package/skill-pre/references/normal/scripts/telemetry.mjs +2102 -0
- package/skill-pre/references/normal/self-update.md +7 -0
- package/skill-pre/references/normal/telemetry.md +70 -0
- package/skill-pre/references/onboarding/assets/keygen.html +927 -0
- package/skill-pre/references/onboarding/flow.md +607 -0
- package/skill-pre/references/onboarding/modules/app-release.md +90 -0
- package/skill-pre/references/onboarding/modules/authorization.md +43 -0
- package/skill-pre/references/onboarding/modules/error-handling.md +62 -0
- package/skill-pre/references/onboarding/modules/product-sign.md +49 -0
- package/skill-pre/references/onboarding/modules/scripts/app.sh +1485 -0
- package/skill-pre/references/onboarding/modules/scripts/ar_sign_apply.sh +331 -0
- package/skill-pre/references/onboarding/modules/scripts/auth.sh +1040 -0
- package/skill-pre/references/onboarding/modules/scripts/download_key_tool.sh +4 -0
- package/skill-pre/references/onboarding/modules/scripts/error_handler.sh +841 -0
- package/skill-pre/references/onboarding/modules/scripts/mcc.sh +1085 -0
- package/skill-pre/references/onboarding/modules/scripts/network_retry.sh +135 -0
- package/skill-pre/references/onboarding/modules/scripts/query_sign_status.sh +105 -0
- package/skill-pre/references/onboarding/modules/scripts/service.sh +528 -0
- package/skill-pre/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
- package/skill-pre/references/onboarding/modules/scripts/upload_screenshots.sh +208 -0
- package/skill-pre/references/onboarding/modules/scripts/upload_special_license.sh +195 -0
- package/skill-pre/references/onboarding/modules/service-registration.md +40 -0
- package/skill-pre/references/runtime-entry.md +99 -0
- package/dist/commands/install-current.d.ts +0 -4
- package/dist/commands/install-current.d.ts.map +0 -1
- package/dist/commands/install-current.js.map +0 -1
- package/dist/commands/install.d.ts +0 -10
- package/dist/commands/install.d.ts.map +0 -1
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/prepare-tools.d.ts +0 -5
- package/dist/commands/prepare-tools.d.ts.map +0 -1
- package/dist/commands/prepare-tools.js.map +0 -1
- package/dist/commands/uninstall.d.ts +0 -10
- package/dist/commands/uninstall.d.ts.map +0 -1
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.d.ts +0 -10
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts +0 -42
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/alipay-cli.d.ts +0 -20
- package/dist/utils/alipay-cli.d.ts.map +0 -1
- package/dist/utils/alipay-cli.js.map +0 -1
- package/dist/utils/config.d.ts +0 -52
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/file.d.ts +0 -77
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/jq.d.ts +0 -17
- package/dist/utils/jq.d.ts.map +0 -1
- package/dist/utils/jq.js.map +0 -1
- package/dist/utils/npm.d.ts +0 -17
- package/dist/utils/npm.d.ts.map +0 -1
- package/dist/utils/npm.js.map +0 -1
- package/dist/utils/shell.d.ts +0 -24
- package/dist/utils/shell.d.ts.map +0 -1
- package/dist/utils/shell.js.map +0 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
|
|
9
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const catalogPath = path.resolve(scriptDir, '../json/customer-messages.json');
|
|
11
|
+
const questionPattern = /[??]|(?:吗|么|嘛|呢)$|是否|能否|可否|要不要|是不是|好了吗|完成了吗|为什么|为何|怎么|怎样|如何|什么意思|什么(?:方式|时候)?|哪个|哪种|何时|什么时候|多少|可不可以|能不能|行不行/u;
|
|
12
|
+
const englishQuestionPattern = /\b(?:can|could|would|should|why|how|what|when|whether)\b/iu;
|
|
13
|
+
const uncertaintyPattern = /可能|大概|也许|或许|不确定|说不好|看情况|再看看|考虑一下|好像|似乎|应该|有风险|有问题|担心|顾虑/u;
|
|
14
|
+
const englishUncertaintyPattern = /\b(?:maybe|perhaps|probably|possibly|unsure)\b/iu;
|
|
15
|
+
const rejectionPattern = /(?:不(?:是|需要|要|用|必|能|可|再)?|别|无(?:需|须|法))(?:再)?(?:继续|推进|执行|处理|开始|提交|确认|同意|允许|批准|创建|操作|往下|下一步|通过|完成)|不可以|不行|不同意|不确认|不允许|不批准|不通过|未确认|未完成|未通过|没(?:有)?完成|还没(?:有)?(?:好|完成|确认|准备)|拒绝|取消|停止|暂停|稍后|晚点|待会|等一下|等等|算了|否定/u;
|
|
16
|
+
const englishRejectionPattern = /\b(?:no|nope|not|don't|do\s+not|stop|cancel|wait|change)\b/iu;
|
|
17
|
+
const conditionalOrChangePattern = /如果|假如|要是|除非|只要|之后再|以后再|但是|不过|只是|前提|再说|(?:修改|调整|改一下|改成|换成|重选|重新选择)|先.{0,20}(?:再|然后)/u;
|
|
18
|
+
const affirmativeIntentPattern = /继续|推进|执行|开始|确认(?:无误)?|确定|同意|允许|批准|可以|没(?:有)?问题|无异议|通过|(?:已经|已)(?:完成|好了)|完成(?:了)?|搞定(?:了)?|弄好了|处理好了|就这么办|往下(?:走|做)|下一步|按(?:此|这个|该|当前)(?:方案)?(?:做|办|执行|推进|处理)|照(?:此|这个|该|当前)(?:方案)?(?:做|办|执行|推进|处理)/u;
|
|
19
|
+
const englishAffirmativeIntentPattern = /\b(?:ok(?:ay)?|yes|confirm(?:ed)?|continue|proceed|approve(?:d)?|go\s+ahead)\b/iu;
|
|
20
|
+
const simpleAffirmativePattern = /^(?:行|行的|行吧)$/u;
|
|
21
|
+
const englishAffirmativeReplies = new Set(['ok', 'okay', 'yes', 'y']);
|
|
22
|
+
const safePrefixes = ['那么就', '那就', '麻烦', '烦请', '嗯嗯', '好的', '我们', '请', '那', '就', '嗯', '我'];
|
|
23
|
+
const safeSuffixes = ['谢谢', '就行', '即可', '吧', '呀', '啊', '哈', '了'];
|
|
24
|
+
|
|
25
|
+
function affirmativeReplies() {
|
|
26
|
+
const catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
|
|
27
|
+
const replies = catalog.interactionReplySets?.affirmative;
|
|
28
|
+
if (!Array.isArray(replies) || replies.length === 0 || replies.some((reply) => typeof reply !== 'string' || !reply)) {
|
|
29
|
+
throw new Error('customer-messages affirmative 回复集合无效');
|
|
30
|
+
}
|
|
31
|
+
return new Set(replies.map(normalizeAffirmativeReply));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function normalizeAffirmativeReply(value) {
|
|
35
|
+
if (typeof value !== 'string') return '';
|
|
36
|
+
return value
|
|
37
|
+
.normalize('NFKC')
|
|
38
|
+
.trim()
|
|
39
|
+
.replace(/[。!!]+$/gu, '')
|
|
40
|
+
.trim()
|
|
41
|
+
.toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isAffirmativeReply(value) {
|
|
45
|
+
const normalized = normalizeAffirmativeReply(value);
|
|
46
|
+
if (normalized === '') return false;
|
|
47
|
+
const replies = affirmativeReplies();
|
|
48
|
+
let compact = normalized.replace(/[\s,,.。!!、;;::]+/gu, '');
|
|
49
|
+
const intentText = compact
|
|
50
|
+
.replace(/(?:不需要|无需|不用)(?:再)?(?:修改|调整|改动|改|确认)/gu, '无异议')
|
|
51
|
+
.replace(/没(?:有)?问题/gu, '无异议');
|
|
52
|
+
if (
|
|
53
|
+
questionPattern.test(intentText)
|
|
54
|
+
|| englishQuestionPattern.test(normalized)
|
|
55
|
+
|| uncertaintyPattern.test(intentText)
|
|
56
|
+
|| englishUncertaintyPattern.test(normalized)
|
|
57
|
+
|| rejectionPattern.test(intentText)
|
|
58
|
+
|| englishRejectionPattern.test(normalized)
|
|
59
|
+
|| conditionalOrChangePattern.test(intentText)
|
|
60
|
+
) return false;
|
|
61
|
+
if (
|
|
62
|
+
replies.has(normalized)
|
|
63
|
+
|| replies.has(compact)
|
|
64
|
+
|| simpleAffirmativePattern.test(compact)
|
|
65
|
+
|| affirmativeIntentPattern.test(compact)
|
|
66
|
+
|| englishAffirmativeIntentPattern.test(normalized)
|
|
67
|
+
) return true;
|
|
68
|
+
|
|
69
|
+
let changed = true;
|
|
70
|
+
while (changed && compact) {
|
|
71
|
+
changed = false;
|
|
72
|
+
for (const prefix of safePrefixes) {
|
|
73
|
+
if (compact.startsWith(prefix)) {
|
|
74
|
+
compact = compact.slice(prefix.length);
|
|
75
|
+
changed = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const suffix of safeSuffixes) {
|
|
80
|
+
if (compact.endsWith(suffix)) {
|
|
81
|
+
compact = compact.slice(0, -suffix.length);
|
|
82
|
+
changed = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (compact === '') return false;
|
|
88
|
+
if (
|
|
89
|
+
replies.has(compact)
|
|
90
|
+
|| simpleAffirmativePattern.test(compact)
|
|
91
|
+
|| affirmativeIntentPattern.test(compact)
|
|
92
|
+
|| englishAffirmativeIntentPattern.test(compact)
|
|
93
|
+
) return true;
|
|
94
|
+
|
|
95
|
+
// Only collapse repeated Latin keystrokes after all negative/ambiguous guards.
|
|
96
|
+
const deduplicatedLatin = compact.replace(/([a-z])\1+/gu, '$1');
|
|
97
|
+
return englishAffirmativeReplies.has(deduplicatedLatin);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function parseArgs(argv) {
|
|
101
|
+
const command = argv[2];
|
|
102
|
+
const args = {};
|
|
103
|
+
for (let index = 3; index < argv.length; index += 1) {
|
|
104
|
+
const token = argv[index];
|
|
105
|
+
if (!token.startsWith('--')) throw new Error(`未知参数 ${token}`);
|
|
106
|
+
const value = argv[index + 1];
|
|
107
|
+
if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
|
|
108
|
+
const name = token.slice(2);
|
|
109
|
+
if (Object.prototype.hasOwnProperty.call(args, name)) throw new Error(`参数 ${token} 重复`);
|
|
110
|
+
args[name] = value;
|
|
111
|
+
index += 1;
|
|
112
|
+
}
|
|
113
|
+
return { command, args };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function required(args, name) {
|
|
117
|
+
const value = args[name];
|
|
118
|
+
if (typeof value !== 'string' || !value) throw new Error(`缺少参数 --${name}`);
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function runInteractionReplyCli(argv = process.argv) {
|
|
123
|
+
const { command, args } = parseArgs(argv);
|
|
124
|
+
if (command !== 'confirm' || typeof args.reply !== 'string' || !args.reply) {
|
|
125
|
+
throw new Error('用法: interaction_reply.mjs confirm --reply <用户原始回复> --input-id <本地用户输入幂等键>');
|
|
126
|
+
}
|
|
127
|
+
required(args, 'input-id');
|
|
128
|
+
const decision = isAffirmativeReply(args.reply) ? 'CONFIRMED' : 'REJECTED';
|
|
129
|
+
process.stderr.write(`${internalPrefix}REPLY_DECISION=${decision}\n`);
|
|
130
|
+
if (decision === 'REJECTED') process.exitCode = 2;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
|
|
134
|
+
try {
|
|
135
|
+
runInteractionReplyCli();
|
|
136
|
+
} catch (error) {
|
|
137
|
+
process.stderr.write(`${internalPrefix}REPLY_VALIDATION_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execFile } from 'node:child_process';
|
|
4
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import fsp from 'node:fs/promises';
|
|
7
|
+
import https from 'node:https';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import process from 'node:process';
|
|
11
|
+
import { promisify } from 'node:util';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const execFileAsync = promisify(execFile);
|
|
15
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const manifestPath = path.resolve(scriptDir, '../json/managed-jq-assets.json');
|
|
17
|
+
const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:JQ_PREPARE=';
|
|
18
|
+
|
|
19
|
+
function readManifest() {
|
|
20
|
+
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
21
|
+
if (
|
|
22
|
+
parsed?.schemaVersion !== 1 ||
|
|
23
|
+
!/^\d+\.\d+\.\d+$/u.test(parsed.version || '') ||
|
|
24
|
+
!Number.isInteger(parsed.downloadTimeoutMs) || parsed.downloadTimeoutMs <= 0 ||
|
|
25
|
+
!Number.isInteger(parsed.idleTimeoutMs) || parsed.idleTimeoutMs <= 0 ||
|
|
26
|
+
!Number.isInteger(parsed.maxBytes) || parsed.maxBytes <= 0 ||
|
|
27
|
+
!Number.isInteger(parsed.maxRedirects) || parsed.maxRedirects < 0 ||
|
|
28
|
+
!parsed.assets || typeof parsed.assets !== 'object' || Array.isArray(parsed.assets)
|
|
29
|
+
) {
|
|
30
|
+
throw new Error('managed jq 资产清单非法');
|
|
31
|
+
}
|
|
32
|
+
return Object.freeze(parsed);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const managedJqManifest = readManifest();
|
|
36
|
+
|
|
37
|
+
export function managedJqPath(homeDir = process.env.HOME || os.homedir()) {
|
|
38
|
+
if (!path.isAbsolute(homeDir) || path.resolve(homeDir) === path.parse(homeDir).root) {
|
|
39
|
+
throw new Error('jq 用户安装目录必须位于绝对 Home 路径下');
|
|
40
|
+
}
|
|
41
|
+
return path.join(path.resolve(homeDir), '.local', 'bin', 'jq');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function resolveManagedJqAsset(platform = process.platform, arch = process.arch) {
|
|
45
|
+
const asset = managedJqManifest.assets[`${platform}-${arch}`];
|
|
46
|
+
return asset ? Object.freeze({ ...asset, version: managedJqManifest.version }) : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function checkManagedJqAtPath(jqPath, expectedVersion = managedJqManifest.version) {
|
|
50
|
+
try {
|
|
51
|
+
const { stdout } = await execFileAsync(jqPath, ['--version'], {
|
|
52
|
+
encoding: 'utf8',
|
|
53
|
+
timeout: 5000,
|
|
54
|
+
windowsHide: true
|
|
55
|
+
});
|
|
56
|
+
const version = String(stdout).trim().replace(/^jq-/u, '');
|
|
57
|
+
if (version !== expectedVersion) return { installed: false };
|
|
58
|
+
const { stdout: smokeOutput } = await execFileAsync(
|
|
59
|
+
jqPath,
|
|
60
|
+
['-n', '-c', '--arg', 'value', 'ok', '{value:$value}'],
|
|
61
|
+
{ encoding: 'utf8', timeout: 5000, windowsHide: true }
|
|
62
|
+
);
|
|
63
|
+
if (String(smokeOutput).trim() !== '{"value":"ok"}') return { installed: false };
|
|
64
|
+
return { installed: true, version, path: jqPath };
|
|
65
|
+
} catch {
|
|
66
|
+
return { installed: false };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function assertAllowedDownloadUrl(value) {
|
|
71
|
+
const url = new URL(value);
|
|
72
|
+
const githubHost = url.hostname === 'github.com' || url.hostname.endsWith('.githubusercontent.com');
|
|
73
|
+
if (url.protocol !== 'https:' || !githubHost || url.username || url.password) {
|
|
74
|
+
throw new Error('jq 下载地址未通过 GitHub HTTPS 白名单校验');
|
|
75
|
+
}
|
|
76
|
+
return url;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function downloadBuffer(
|
|
80
|
+
urlValue,
|
|
81
|
+
deadline = Date.now() + managedJqManifest.downloadTimeoutMs,
|
|
82
|
+
redirectCount = 0
|
|
83
|
+
) {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
let url;
|
|
86
|
+
try {
|
|
87
|
+
url = assertAllowedDownloadUrl(urlValue);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
reject(error);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const remaining = deadline - Date.now();
|
|
94
|
+
if (remaining <= 0) {
|
|
95
|
+
reject(new Error(`jq 下载超过 ${managedJqManifest.downloadTimeoutMs / 1000} 秒`));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let settled = false;
|
|
100
|
+
const request = https.get(url, { headers: { 'User-Agent': 'alipay-aipay-jq-installer' } });
|
|
101
|
+
const totalTimer = setTimeout(() => {
|
|
102
|
+
request.destroy(new Error(`jq 下载超过 ${managedJqManifest.downloadTimeoutMs / 1000} 秒`));
|
|
103
|
+
}, remaining);
|
|
104
|
+
|
|
105
|
+
function fail(error) {
|
|
106
|
+
if (settled) return;
|
|
107
|
+
settled = true;
|
|
108
|
+
clearTimeout(totalTimer);
|
|
109
|
+
reject(error);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
request.setTimeout(Math.min(managedJqManifest.idleTimeoutMs, remaining), () => {
|
|
113
|
+
request.destroy(new Error(`jq 下载连续 ${managedJqManifest.idleTimeoutMs / 1000} 秒无响应`));
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
request.on('response', (response) => {
|
|
117
|
+
const status = response.statusCode || 0;
|
|
118
|
+
const location = response.headers.location;
|
|
119
|
+
if (status >= 300 && status < 400 && location) {
|
|
120
|
+
response.resume();
|
|
121
|
+
clearTimeout(totalTimer);
|
|
122
|
+
settled = true;
|
|
123
|
+
if (redirectCount >= managedJqManifest.maxRedirects) {
|
|
124
|
+
reject(new Error('jq 下载重定向次数过多'));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
downloadBuffer(new URL(location, url).toString(), deadline, redirectCount + 1).then(resolve, reject);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (status !== 200) {
|
|
131
|
+
response.resume();
|
|
132
|
+
fail(new Error(`jq 下载返回 HTTP ${status || 'UNKNOWN'}`));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const declaredLength = Number(response.headers['content-length'] || 0);
|
|
137
|
+
if (declaredLength > managedJqManifest.maxBytes) {
|
|
138
|
+
response.resume();
|
|
139
|
+
fail(new Error('jq 下载文件超过大小上限'));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const chunks = [];
|
|
144
|
+
let size = 0;
|
|
145
|
+
response.on('data', (chunk) => {
|
|
146
|
+
size += chunk.length;
|
|
147
|
+
if (size > managedJqManifest.maxBytes) {
|
|
148
|
+
response.destroy(new Error('jq 下载文件超过大小上限'));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
chunks.push(chunk);
|
|
152
|
+
});
|
|
153
|
+
response.on('end', () => {
|
|
154
|
+
if (settled) return;
|
|
155
|
+
settled = true;
|
|
156
|
+
clearTimeout(totalTimer);
|
|
157
|
+
resolve(Buffer.concat(chunks));
|
|
158
|
+
});
|
|
159
|
+
response.on('error', fail);
|
|
160
|
+
});
|
|
161
|
+
request.on('error', fail);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export async function installManagedJqAsset(asset, targetPath, downloader = downloadBuffer) {
|
|
166
|
+
const targetDir = path.dirname(targetPath);
|
|
167
|
+
const tempPath = path.join(targetDir, `.jq-${process.pid}-${randomBytes(6).toString('hex')}.tmp`);
|
|
168
|
+
await fsp.mkdir(targetDir, { recursive: true, mode: 0o700 });
|
|
169
|
+
try {
|
|
170
|
+
const body = await downloader(asset.url);
|
|
171
|
+
const digest = createHash('sha256').update(body).digest('hex');
|
|
172
|
+
if (digest !== asset.sha256) throw new Error('jq 下载文件 SHA-256 校验失败');
|
|
173
|
+
await fsp.writeFile(tempPath, body, { flag: 'wx', mode: 0o700 });
|
|
174
|
+
await fsp.chmod(tempPath, 0o755);
|
|
175
|
+
const check = await checkManagedJqAtPath(tempPath, asset.version);
|
|
176
|
+
if (!check.installed) throw new Error('jq 用户级文件版本或 JSON 功能验证失败');
|
|
177
|
+
await fsp.rename(tempPath, targetPath);
|
|
178
|
+
return { ...check, path: targetPath };
|
|
179
|
+
} finally {
|
|
180
|
+
await fsp.rm(tempPath, { force: true }).catch(() => undefined);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export async function prepareManagedJq(options = {}) {
|
|
185
|
+
const platform = options.platform || process.platform;
|
|
186
|
+
const arch = options.arch || process.arch;
|
|
187
|
+
const asset = resolveManagedJqAsset(platform, arch);
|
|
188
|
+
if (!asset) return { status: 'UNSUPPORTED', platform, arch };
|
|
189
|
+
const targetPath = managedJqPath(options.homeDir);
|
|
190
|
+
const existing = await checkManagedJqAtPath(targetPath, asset.version);
|
|
191
|
+
if (existing.installed) return { status: 'READY', source: 'EXISTING', ...existing };
|
|
192
|
+
const installed = await installManagedJqAsset(asset, targetPath, options.downloader);
|
|
193
|
+
return { status: 'READY', source: 'INSTALLED', ...installed };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export async function runManagedJqCli(argv = process.argv) {
|
|
197
|
+
if (argv.length !== 3 || argv[2] !== 'prepare') throw new Error('用法: managed_jq.mjs prepare');
|
|
198
|
+
try {
|
|
199
|
+
const result = await prepareManagedJq();
|
|
200
|
+
process.stderr.write(`${internalPrefix}${result.status}\n`);
|
|
201
|
+
return result.status === 'READY' ? 0 : 2;
|
|
202
|
+
} catch {
|
|
203
|
+
process.stderr.write(`${internalPrefix}FAILED\n`);
|
|
204
|
+
return 1;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
209
|
+
runManagedJqCli().then((code) => {
|
|
210
|
+
process.exitCode = code;
|
|
211
|
+
}).catch((error) => {
|
|
212
|
+
process.stderr.write(`${internalPrefix}FAILED\n`);
|
|
213
|
+
process.exitCode = 1;
|
|
214
|
+
});
|
|
215
|
+
}
|