@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,237 @@
|
|
|
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
|
+
import { checklistForProduct } from './checklist_sections.mjs';
|
|
9
|
+
import { createChecklistScopeReceipt } from './integration_message_runner.mjs';
|
|
10
|
+
|
|
11
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const referencesDir = path.resolve(scriptDir, '../..');
|
|
13
|
+
const productTypes = new Set(['aipay', 'webpay', 'apppay']);
|
|
14
|
+
const flowDefinitions = Object.freeze({
|
|
15
|
+
integration: {
|
|
16
|
+
source: path.join(referencesDir, 'integration/flow.md'),
|
|
17
|
+
prefix: 'INTEGRATION',
|
|
18
|
+
sharedGuard: 'INTEGRATION-GUARDS',
|
|
19
|
+
productGuards: { aipay: 'INTEGRATION-GUARDS-AIPAY' }
|
|
20
|
+
},
|
|
21
|
+
onboarding: {
|
|
22
|
+
source: path.join(referencesDir, 'onboarding/flow.md'),
|
|
23
|
+
prefix: 'ONBOARDING',
|
|
24
|
+
sharedGuard: 'ONBOARDING-GUARDS-SHARED'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function definitionFor(flow) {
|
|
29
|
+
const definition = flowDefinitions[flow];
|
|
30
|
+
if (!definition) throw new Error('flow 仅支持 integration 或 onboarding');
|
|
31
|
+
return definition;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function marker(name, boundary) {
|
|
35
|
+
return `<!-- ALIPAY_AIPAY_FLOW:${name}:${boundary} -->`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function countOccurrences(source, needle) {
|
|
39
|
+
let count = 0;
|
|
40
|
+
let offset = 0;
|
|
41
|
+
while ((offset = source.indexOf(needle, offset)) >= 0) {
|
|
42
|
+
count += 1;
|
|
43
|
+
offset += needle.length;
|
|
44
|
+
}
|
|
45
|
+
return count;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function extractGeneratedBlock(source, name) {
|
|
49
|
+
const startMarker = `<!-- GENERATED:${name}:START -->`;
|
|
50
|
+
const endMarker = `<!-- GENERATED:${name}:END -->`;
|
|
51
|
+
if (countOccurrences(source, startMarker) !== 1 || countOccurrences(source, endMarker) !== 1) {
|
|
52
|
+
throw new Error(`生成护栏区块 ${name} 必须且只能有一组 START/END marker`);
|
|
53
|
+
}
|
|
54
|
+
const start = source.indexOf(startMarker) + startMarker.length;
|
|
55
|
+
const end = source.indexOf(endMarker, start);
|
|
56
|
+
if (end < start) throw new Error(`生成护栏区块 ${name} marker 顺序非法`);
|
|
57
|
+
const block = source.slice(start, end).trim();
|
|
58
|
+
if (!block) throw new Error(`生成护栏区块 ${name} 不能为空`);
|
|
59
|
+
return block;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function extractFlowBlock(source, name) {
|
|
63
|
+
const startMarker = marker(name, 'START');
|
|
64
|
+
const endMarker = marker(name, 'END');
|
|
65
|
+
if (countOccurrences(source, startMarker) !== 1 || countOccurrences(source, endMarker) !== 1) {
|
|
66
|
+
throw new Error(`flow 区块 ${name} 必须且只能有一组 START/END marker`);
|
|
67
|
+
}
|
|
68
|
+
const start = source.indexOf(startMarker) + startMarker.length;
|
|
69
|
+
const end = source.indexOf(endMarker, start);
|
|
70
|
+
if (end < start) throw new Error(`flow 区块 ${name} marker 顺序非法`);
|
|
71
|
+
const block = source.slice(start, end).trim();
|
|
72
|
+
if (!block) throw new Error(`flow 区块 ${name} 不能为空`);
|
|
73
|
+
return block;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function flowSource(flow) {
|
|
77
|
+
return fs.readFileSync(definitionFor(flow).source, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function flowBlockNames(flow) {
|
|
81
|
+
const source = flowSource(flow);
|
|
82
|
+
const names = [];
|
|
83
|
+
for (const match of source.matchAll(/<!-- ALIPAY_AIPAY_FLOW:([A-Z_]+):START -->/gu)) {
|
|
84
|
+
if (!names.includes(match[1])) names.push(match[1]);
|
|
85
|
+
}
|
|
86
|
+
for (const name of names) extractFlowBlock(source, name);
|
|
87
|
+
return names;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function phaseName(flow, blockName) {
|
|
91
|
+
const prefix = `${definitionFor(flow).prefix}_`;
|
|
92
|
+
if (!blockName.startsWith(prefix)) throw new Error(`flow 区块前缀非法:${blockName}`);
|
|
93
|
+
return blockName.slice(prefix.length).toLowerCase().replaceAll('_', '-');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function phaseBlockName(flow, phase) {
|
|
97
|
+
return `${definitionFor(flow).prefix}_${phase.toUpperCase().replaceAll('-', '_')}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function declaredProducts(block) {
|
|
101
|
+
const matches = [...block.matchAll(/<!-- ALIPAY_AIPAY_PRODUCTS:([a-z,]+) -->/gu)];
|
|
102
|
+
if (matches.length > 1) throw new Error('每个 flow 阶段最多声明一次 ALIPAY_AIPAY_PRODUCTS');
|
|
103
|
+
if (matches.length === 0) return null;
|
|
104
|
+
const products = matches[0][1].split(',');
|
|
105
|
+
if (products.some((product) => !productTypes.has(product))) throw new Error('flow 阶段产品声明非法');
|
|
106
|
+
return new Set(products);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function filterProductSections(source, productType) {
|
|
110
|
+
const sectionPattern = /<!-- ALIPAY_AIPAY_PRODUCT:([a-z,]+):START -->([\s\S]*?)<!-- ALIPAY_AIPAY_PRODUCT:END -->/gu;
|
|
111
|
+
const filtered = source.replace(sectionPattern, (_, list, body) => {
|
|
112
|
+
const products = list.split(',');
|
|
113
|
+
if (products.some((product) => !productTypes.has(product))) throw new Error('flow 产品区块声明非法');
|
|
114
|
+
return !productType || products.includes(productType) ? body.trim() : '';
|
|
115
|
+
});
|
|
116
|
+
if (/ALIPAY_AIPAY_PRODUCT:/u.test(filtered)) throw new Error('flow 产品区块 marker 不完整或发生嵌套');
|
|
117
|
+
return filtered;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function cleanDirectives(block, productType, sharedGuard) {
|
|
121
|
+
return filterProductSections(block, productType)
|
|
122
|
+
.replace(/<!-- GENERATED:([A-Z0-9-]+):START -->([\s\S]*?)<!-- GENERATED:\1:END -->/gu,
|
|
123
|
+
(_, name, body) => name !== sharedGuard && name.startsWith('ONBOARDING-GUARDS-') ? body.trim() : '')
|
|
124
|
+
.replace(/<!-- ALIPAY_AIPAY_PRODUCTS:[a-z,]+ -->/gu, '')
|
|
125
|
+
.replace(/<!-- ALIPAY_AIPAY_STAGE:[a-z0-9._-]+(?: products=[a-z,]+)? -->/gu, '')
|
|
126
|
+
.trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function flowPhaseNames(flow, { productType } = {}) {
|
|
130
|
+
if (productType !== undefined && !productTypes.has(productType)) throw new Error('product-type 非法');
|
|
131
|
+
const source = flowSource(flow);
|
|
132
|
+
const coreName = `${definitionFor(flow).prefix}_CORE`;
|
|
133
|
+
return flowBlockNames(flow)
|
|
134
|
+
.filter((name) => name !== coreName && !name.includes('_FRAGMENT_'))
|
|
135
|
+
.filter((name) => {
|
|
136
|
+
const products = declaredProducts(extractFlowBlock(source, name));
|
|
137
|
+
return !products || !productType || products.has(productType);
|
|
138
|
+
})
|
|
139
|
+
.map((name) => phaseName(flow, name));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function loadFlowBundle(flow, phase, { productType } = {}) {
|
|
143
|
+
if (productType !== undefined && !productTypes.has(productType)) throw new Error('product-type 非法');
|
|
144
|
+
const definition = definitionFor(flow);
|
|
145
|
+
const source = flowSource(flow);
|
|
146
|
+
const blockName = phaseBlockName(flow, phase);
|
|
147
|
+
if (!flowBlockNames(flow).includes(blockName) || blockName.includes('_FRAGMENT_')) {
|
|
148
|
+
throw new Error(`${flow} phase 非法;允许值:${flowPhaseNames(flow, { productType }).join('、')}`);
|
|
149
|
+
}
|
|
150
|
+
const phaseBlock = extractFlowBlock(source, blockName);
|
|
151
|
+
const products = declaredProducts(phaseBlock);
|
|
152
|
+
if (products && productType && !products.has(productType)) {
|
|
153
|
+
throw new Error(`${flow} ${phase} phase 不适用于 ${productType}`);
|
|
154
|
+
}
|
|
155
|
+
const loadsCore = (flow === 'integration' && phase === 'development')
|
|
156
|
+
|| (flow === 'onboarding' && phase === 'execute');
|
|
157
|
+
const blocks = loadsCore
|
|
158
|
+
? [extractFlowBlock(source, `${definition.prefix}_CORE`), phaseBlock]
|
|
159
|
+
: [phaseBlock];
|
|
160
|
+
if (flow === 'integration' && phase === 'checklist') {
|
|
161
|
+
if (!productType) throw new Error('integration checklist phase 缺少 product-type');
|
|
162
|
+
blocks.push(`## 当前产品适用校验清单\n\n${checklistForProduct(productType).markdown}`);
|
|
163
|
+
}
|
|
164
|
+
return [
|
|
165
|
+
`<!-- ALIPAY_AIPAY_REFERENCE_BUNDLE flow=${flow} phase=${phase}; 仅供内部执行,禁止对客 -->`,
|
|
166
|
+
extractGeneratedBlock(source, definition.sharedGuard),
|
|
167
|
+
productType && definition.productGuards?.[productType]
|
|
168
|
+
? extractGeneratedBlock(source, definition.productGuards[productType])
|
|
169
|
+
: '',
|
|
170
|
+
...blocks.map((block) => cleanDirectives(block, productType, definition.sharedGuard)).filter(Boolean)
|
|
171
|
+
].filter(Boolean).join('\n\n');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function productFromRoute(route) {
|
|
175
|
+
return route.match(/(?:^|_)(aipay|webpay|apppay)(?:_|$)/u)?.[1];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function flowBundlesForRoute(route) {
|
|
179
|
+
const productType = productFromRoute(route);
|
|
180
|
+
let flows;
|
|
181
|
+
if (route === 'full_process_first_wait') return [];
|
|
182
|
+
if (route.startsWith('full_process_')) flows = ['integration', 'onboarding'];
|
|
183
|
+
else if (route.startsWith('integration_')) flows = ['integration'];
|
|
184
|
+
else if (route.startsWith('onboarding_')) flows = ['onboarding'];
|
|
185
|
+
else throw new Error(`无法从 route 派生 flow:${route}`);
|
|
186
|
+
if (route.endsWith('_first_wait')) flows = [flows[0]];
|
|
187
|
+
return flows.flatMap((flow) => {
|
|
188
|
+
const availablePhases = flowPhaseNames(flow, { productType });
|
|
189
|
+
const phases = route.endsWith('_first_wait') ? [availablePhases[0]] : availablePhases;
|
|
190
|
+
return phases.map((phase) => ({
|
|
191
|
+
flow,
|
|
192
|
+
phase,
|
|
193
|
+
productType,
|
|
194
|
+
source: loadFlowBundle(flow, phase, { productType })
|
|
195
|
+
}));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function parseOptions(argv) {
|
|
200
|
+
const options = {};
|
|
201
|
+
for (let index = 4; index < argv.length; index += 1) {
|
|
202
|
+
const token = argv[index];
|
|
203
|
+
if (!token.startsWith('--')) throw new Error(`未知参数 ${token}`);
|
|
204
|
+
const value = argv[index + 1];
|
|
205
|
+
if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
|
|
206
|
+
const name = token.slice(2);
|
|
207
|
+
if (Object.prototype.hasOwnProperty.call(options, name)) throw new Error(`参数 ${token} 重复`);
|
|
208
|
+
options[name] = value;
|
|
209
|
+
index += 1;
|
|
210
|
+
}
|
|
211
|
+
return options;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function runFlowCli(argv = process.argv) {
|
|
215
|
+
const flow = argv[2];
|
|
216
|
+
const phase = argv[3];
|
|
217
|
+
if (!flow || !phase) throw new Error('用法: flow_loader.mjs <integration|onboarding> <phase> [阶段参数]');
|
|
218
|
+
const options = parseOptions(argv);
|
|
219
|
+
const productType = options['product-type'];
|
|
220
|
+
if (flow === 'integration' && phase === 'checklist') {
|
|
221
|
+
const projectPath = options['project-path'];
|
|
222
|
+
if (!projectPath) throw new Error('integration checklist phase 缺少 --project-path');
|
|
223
|
+
if (!productType) throw new Error('integration checklist phase 缺少 --product-type');
|
|
224
|
+
process.stderr.write(`ALIPAY_AIPAY_INTERNAL:CHECKLIST_SCOPE_RECEIPT=${createChecklistScopeReceipt(productType, projectPath)}\n`);
|
|
225
|
+
}
|
|
226
|
+
const source = flowSource(flow);
|
|
227
|
+
process.stdout.write(`${loadFlowBundle(flow, phase, { productType })}\n`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
231
|
+
try {
|
|
232
|
+
runFlowCli();
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error(`FLOW_LOADER_ERROR:${error.message}`);
|
|
235
|
+
process.exitCode = 1;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
import { checklistForProduct } from './checklist_sections.mjs';
|
|
9
|
+
|
|
10
|
+
const internalPrefix = 'ALIPAY_AIPAY_INTERNAL:';
|
|
11
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const integrationDir = path.resolve(scriptDir, '../../integration');
|
|
13
|
+
const modulesDir = path.join(integrationDir, 'modules');
|
|
14
|
+
const interfaceGuidePath = path.join(modulesDir, 'interface-guide.md');
|
|
15
|
+
const productTypes = new Set(['aipay', 'webpay', 'apppay']);
|
|
16
|
+
|
|
17
|
+
const languageRules = Object.freeze({
|
|
18
|
+
java: { name: 'Java', directory: 'java' },
|
|
19
|
+
python: { name: 'Python', directory: 'python' },
|
|
20
|
+
nodejs: { name: 'Node.js', directory: 'nodejs' },
|
|
21
|
+
csharp: { name: 'C#', directory: 'csharp' },
|
|
22
|
+
php: { name: 'PHP', directory: 'php' }
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
const command = argv[2];
|
|
27
|
+
const args = {};
|
|
28
|
+
for (let index = 3; index < argv.length; index += 1) {
|
|
29
|
+
const token = argv[index];
|
|
30
|
+
if (!token.startsWith('--')) throw new Error(`未知参数 ${token}`);
|
|
31
|
+
const value = argv[index + 1];
|
|
32
|
+
if (value === undefined || value.startsWith('--')) throw new Error(`参数 ${token} 缺少取值`);
|
|
33
|
+
const name = token.slice(2);
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(args, name)) throw new Error(`参数 ${token} 重复`);
|
|
35
|
+
args[name] = value;
|
|
36
|
+
index += 1;
|
|
37
|
+
}
|
|
38
|
+
return { command, args };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function required(args, name) {
|
|
42
|
+
const value = args[name];
|
|
43
|
+
if (typeof value !== 'string' || !value) throw new Error(`缺少参数 --${name}`);
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function normalizeLanguage(value) {
|
|
48
|
+
const compact = value.trim().toLowerCase().replace(/[\s_.-]+/gu, '');
|
|
49
|
+
if (compact === 'java') return languageRules.java;
|
|
50
|
+
if (compact === 'python' || compact === 'python3' || compact === 'py') return languageRules.python;
|
|
51
|
+
if (compact === 'node' || compact === 'nodejs' || compact === 'javascript' || compact === 'js') return languageRules.nodejs;
|
|
52
|
+
if (compact === 'c#' || compact === 'csharp' || compact === 'dotnet' || compact === 'net') return languageRules.csharp;
|
|
53
|
+
if (compact === 'php') return languageRules.php;
|
|
54
|
+
throw new Error('server-language 非法,仅支持 Java、Python、Node.js、C#、PHP');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function relativeToIntegration(absolutePath) {
|
|
58
|
+
return path.relative(integrationDir, absolutePath).split(path.sep).join('/');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function codeValues(value) {
|
|
62
|
+
return [...value.matchAll(/`([^`]+)`/gu)].map((match) => match[1]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function productRoutes() {
|
|
66
|
+
const source = fs.readFileSync(interfaceGuidePath, 'utf8');
|
|
67
|
+
const lines = source.split(/\r?\n/u);
|
|
68
|
+
const header = lines.findIndex((line) => line.startsWith('| productType | 产品 |'));
|
|
69
|
+
if (header < 0) throw new Error('interface-guide 缺少默认读取路由事实表');
|
|
70
|
+
const routes = {};
|
|
71
|
+
for (let index = header + 2; index < lines.length && lines[index].startsWith('|'); index += 1) {
|
|
72
|
+
const cells = lines[index].slice(1, -1).split('|').map((cell) => cell.trim());
|
|
73
|
+
if (cells.length !== 6) throw new Error('interface-guide 默认读取路由表列数非法');
|
|
74
|
+
const [productType] = codeValues(cells[0]);
|
|
75
|
+
const [sandboxAction] = codeValues(cells[4]);
|
|
76
|
+
const sandboxReferences = codeValues(cells[5]);
|
|
77
|
+
if (!productTypes.has(productType) || routes[productType]) throw new Error('interface-guide productType 非法或重复');
|
|
78
|
+
const contracts = codeValues(cells[2]).map((value) => `modules/${value}`);
|
|
79
|
+
const exampleDirectories = codeValues(cells[3]);
|
|
80
|
+
if (!cells[1] || contracts.length === 0 || exampleDirectories.length === 0 || !sandboxAction || sandboxReferences.length > 1) {
|
|
81
|
+
throw new Error(`interface-guide 的 ${productType} 路由字段不完整`);
|
|
82
|
+
}
|
|
83
|
+
routes[productType] = {
|
|
84
|
+
name: cells[1],
|
|
85
|
+
contracts,
|
|
86
|
+
exampleDirectories,
|
|
87
|
+
sandboxAction,
|
|
88
|
+
sandboxReference: sandboxReferences[0] ? `modules/${sandboxReferences[0]}` : null
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (Object.keys(routes).length !== productTypes.size) throw new Error('interface-guide 产品路由不完整');
|
|
92
|
+
return routes;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function existingRoutePaths(route) {
|
|
96
|
+
const paths = [...route.contracts, ...(route.sandboxReference ? [route.sandboxReference] : [])];
|
|
97
|
+
for (const relativePath of paths) {
|
|
98
|
+
if (!fs.statSync(path.join(integrationDir, relativePath)).isFile()) throw new Error(`路由文件不存在:${relativePath}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function examplePathsFor(route, languageDirectory) {
|
|
103
|
+
const roots = route.exampleDirectories.map((directory) => path.join(modulesDir, 'code-examples', languageDirectory, directory));
|
|
104
|
+
const examples = roots.flatMap((directory) => fs.readdirSync(directory, { withFileTypes: true })
|
|
105
|
+
.filter((entry) => entry.isFile())
|
|
106
|
+
.map((entry) => relativeToIntegration(path.join(directory, entry.name))));
|
|
107
|
+
if (examples.length === 0) throw new Error('当前产品和语言没有本地代码示例');
|
|
108
|
+
return examples.sort((left, right) => left.localeCompare(right));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function resolveIntegrationContext(productType, serverLanguage) {
|
|
112
|
+
const product = productRoutes()[productType];
|
|
113
|
+
if (!product) throw new Error('product-type 非法,仅支持 aipay、webpay、apppay');
|
|
114
|
+
const language = normalizeLanguage(serverLanguage);
|
|
115
|
+
existingRoutePaths(product);
|
|
116
|
+
return {
|
|
117
|
+
schema_ver: 1,
|
|
118
|
+
product_type: productType,
|
|
119
|
+
product_name: product.name,
|
|
120
|
+
server_language: language.name,
|
|
121
|
+
sdk_reference: 'modules/alipay-sdk-reminder.md',
|
|
122
|
+
contracts: product.contracts,
|
|
123
|
+
examples: examplePathsFor(product, language.directory),
|
|
124
|
+
checklist: {
|
|
125
|
+
delivery_phase: 'checklist',
|
|
126
|
+
sections: checklistForProduct(productType).sections
|
|
127
|
+
},
|
|
128
|
+
sandbox_acceptance: {
|
|
129
|
+
action: product.sandboxAction,
|
|
130
|
+
reference: product.sandboxReference
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function runIntegrationContextCli(argv = process.argv) {
|
|
136
|
+
const { command, args } = parseArgs(argv);
|
|
137
|
+
if (command !== 'resolve') {
|
|
138
|
+
throw new Error('用法: integration_context_runner.mjs resolve --product-type <aipay|webpay|apppay> --server-language <language>');
|
|
139
|
+
}
|
|
140
|
+
const context = resolveIntegrationContext(required(args, 'product-type'), required(args, 'server-language'));
|
|
141
|
+
process.stderr.write(`${internalPrefix}INTEGRATION_CONTEXT=${JSON.stringify(context)}\n`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
145
|
+
try {
|
|
146
|
+
runIntegrationContextCli();
|
|
147
|
+
} catch (error) {
|
|
148
|
+
process.stderr.write(`${internalPrefix}INTEGRATION_CONTEXT_ERROR=${String(error?.message || error).replace(/[\r\n]/gu, ' ')}\n`);
|
|
149
|
+
process.exitCode = 1;
|
|
150
|
+
}
|
|
151
|
+
}
|