@atbas/m-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builder/transaction-builder.d.ts +53 -0
- package/dist/builder/transaction-builder.d.ts.map +1 -0
- package/dist/builder/transaction-builder.js +159 -0
- package/dist/builder/transaction-builder.js.map +1 -0
- package/dist/catalogue/default-catalogue.d.ts +18 -0
- package/dist/catalogue/default-catalogue.d.ts.map +1 -0
- package/dist/catalogue/default-catalogue.js +21 -0
- package/dist/catalogue/default-catalogue.js.map +1 -0
- package/dist/catalogue/endpoints.d.ts +22 -0
- package/dist/catalogue/endpoints.d.ts.map +1 -0
- package/dist/catalogue/endpoints.js +24 -0
- package/dist/catalogue/endpoints.js.map +1 -0
- package/dist/catalogue/flows.d.ts +32 -0
- package/dist/catalogue/flows.d.ts.map +1 -0
- package/dist/catalogue/flows.js +64 -0
- package/dist/catalogue/flows.js.map +1 -0
- package/dist/catalogue/hash-options.d.ts +112 -0
- package/dist/catalogue/hash-options.d.ts.map +1 -0
- package/dist/catalogue/hash-options.js +151 -0
- package/dist/catalogue/hash-options.js.map +1 -0
- package/dist/catalogue/types.d.ts +279 -0
- package/dist/catalogue/types.d.ts.map +1 -0
- package/dist/catalogue/types.js +360 -0
- package/dist/catalogue/types.js.map +1 -0
- package/dist/codegen/generate.d.ts +14 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/generate.js +490 -0
- package/dist/codegen/generate.js.map +1 -0
- package/dist/codegen/languages/node.d.ts +3 -0
- package/dist/codegen/languages/node.d.ts.map +1 -0
- package/dist/codegen/languages/node.js +32 -0
- package/dist/codegen/languages/node.js.map +1 -0
- package/dist/codegen/languages/php.d.ts +3 -0
- package/dist/codegen/languages/php.d.ts.map +1 -0
- package/dist/codegen/languages/php.js +27 -0
- package/dist/codegen/languages/php.js.map +1 -0
- package/dist/codegen/languages/python.d.ts +3 -0
- package/dist/codegen/languages/python.d.ts.map +1 -0
- package/dist/codegen/languages/python.js +27 -0
- package/dist/codegen/languages/python.js.map +1 -0
- package/dist/codegen/renderer.d.ts +24 -0
- package/dist/codegen/renderer.d.ts.map +1 -0
- package/dist/codegen/renderer.js +59 -0
- package/dist/codegen/renderer.js.map +1 -0
- package/dist/codegen/types.d.ts +50 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +5 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/config/credentials.d.ts +64 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +216 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/environment.d.ts +23 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +54 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/core/dependencies.d.ts +43 -0
- package/dist/core/dependencies.d.ts.map +1 -0
- package/dist/core/dependencies.js +2 -0
- package/dist/core/dependencies.js.map +1 -0
- package/dist/core/registry.d.ts +33 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +13 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/server.d.ts +61 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +90 -0
- package/dist/core/server.js.map +1 -0
- package/dist/dependencies.d.ts +28 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +2 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/diagnostics/diagnose.d.ts +43 -0
- package/dist/diagnostics/diagnose.d.ts.map +1 -0
- package/dist/diagnostics/diagnose.js +121 -0
- package/dist/diagnostics/diagnose.js.map +1 -0
- package/dist/domain/amount.d.ts +157 -0
- package/dist/domain/amount.d.ts.map +1 -0
- package/dist/domain/amount.js +275 -0
- package/dist/domain/amount.js.map +1 -0
- package/dist/domain/datetime.d.ts +95 -0
- package/dist/domain/datetime.d.ts.map +1 -0
- package/dist/domain/datetime.js +211 -0
- package/dist/domain/datetime.js.map +1 -0
- package/dist/domain/response-codes.d.ts +116 -0
- package/dist/domain/response-codes.d.ts.map +1 -0
- package/dist/domain/response-codes.js +380 -0
- package/dist/domain/response-codes.js.map +1 -0
- package/dist/domain/secure-hash.d.ts +78 -0
- package/dist/domain/secure-hash.d.ts.map +1 -0
- package/dist/domain/secure-hash.js +69 -0
- package/dist/domain/secure-hash.js.map +1 -0
- package/dist/domain/signature/jazzcash.d.ts +56 -0
- package/dist/domain/signature/jazzcash.d.ts.map +1 -0
- package/dist/domain/signature/jazzcash.js +214 -0
- package/dist/domain/signature/jazzcash.js.map +1 -0
- package/dist/domain/signature/registry.d.ts +69 -0
- package/dist/domain/signature/registry.d.ts.map +1 -0
- package/dist/domain/signature/registry.js +92 -0
- package/dist/domain/signature/registry.js.map +1 -0
- package/dist/domain/signature/scheme.d.ts +349 -0
- package/dist/domain/signature/scheme.d.ts.map +1 -0
- package/dist/domain/signature/scheme.js +398 -0
- package/dist/domain/signature/scheme.js.map +1 -0
- package/dist/domain/txn-ref.d.ts +76 -0
- package/dist/domain/txn-ref.d.ts.map +1 -0
- package/dist/domain/txn-ref.js +126 -0
- package/dist/domain/txn-ref.js.map +1 -0
- package/dist/domain/types.d.ts +45 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +70 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/errors.d.ts +84 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +87 -0
- package/dist/errors.js.map +1 -0
- package/dist/gateway/checkout-form.d.ts +16 -0
- package/dist/gateway/checkout-form.d.ts.map +1 -0
- package/dist/gateway/checkout-form.js +103 -0
- package/dist/gateway/checkout-form.js.map +1 -0
- package/dist/gateway/checkout-output.d.ts +70 -0
- package/dist/gateway/checkout-output.d.ts.map +1 -0
- package/dist/gateway/checkout-output.js +199 -0
- package/dist/gateway/checkout-output.js.map +1 -0
- package/dist/gateway/guards.d.ts +37 -0
- package/dist/gateway/guards.d.ts.map +1 -0
- package/dist/gateway/guards.js +44 -0
- package/dist/gateway/guards.js.map +1 -0
- package/dist/gateway/http-client.d.ts +42 -0
- package/dist/gateway/http-client.d.ts.map +1 -0
- package/dist/gateway/http-client.js +153 -0
- package/dist/gateway/http-client.js.map +1 -0
- package/dist/gateway/rest-client.d.ts +42 -0
- package/dist/gateway/rest-client.d.ts.map +1 -0
- package/dist/gateway/rest-client.js +241 -0
- package/dist/gateway/rest-client.js.map +1 -0
- package/dist/gateway/transport.d.ts +31 -0
- package/dist/gateway/transport.d.ts.map +1 -0
- package/dist/gateway/transport.js +73 -0
- package/dist/gateway/transport.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +38 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +274 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/harnesses.d.ts +74 -0
- package/dist/install/harnesses.d.ts.map +1 -0
- package/dist/install/harnesses.js +263 -0
- package/dist/install/harnesses.js.map +1 -0
- package/dist/knowledge/corpus.d.ts +15 -0
- package/dist/knowledge/corpus.d.ts.map +1 -0
- package/dist/knowledge/corpus.js +129 -0
- package/dist/knowledge/corpus.js.map +1 -0
- package/dist/knowledge/search.d.ts +29 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +181 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/source.d.ts +60 -0
- package/dist/knowledge/source.d.ts.map +1 -0
- package/dist/knowledge/source.js +91 -0
- package/dist/knowledge/source.js.map +1 -0
- package/dist/knowledge/types.d.ts +40 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +19 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/paths.d.ts +26 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +106 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts/integration-walkthrough.d.ts +11 -0
- package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
- package/dist/prompts/integration-walkthrough.js +52 -0
- package/dist/prompts/integration-walkthrough.js.map +1 -0
- package/dist/prompts/register.d.ts +4 -0
- package/dist/prompts/register.d.ts.map +1 -0
- package/dist/prompts/register.js +4 -0
- package/dist/prompts/register.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -0
- package/dist/resources/knowledge-resources.d.ts +5 -0
- package/dist/resources/knowledge-resources.d.ts.map +1 -0
- package/dist/resources/knowledge-resources.js +121 -0
- package/dist/resources/knowledge-resources.js.map +1 -0
- package/dist/resources/register.d.ts +4 -0
- package/dist/resources/register.d.ts.map +1 -0
- package/dist/resources/register.js +8 -0
- package/dist/resources/register.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/logger.d.ts +31 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +67 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/redaction.d.ts +88 -0
- package/dist/telemetry/redaction.d.ts.map +1 -0
- package/dist/telemetry/redaction.js +238 -0
- package/dist/telemetry/redaction.js.map +1 -0
- package/dist/tools/build-transaction-parameters.d.ts +10 -0
- package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
- package/dist/tools/build-transaction-parameters.js +154 -0
- package/dist/tools/build-transaction-parameters.js.map +1 -0
- package/dist/tools/call-context.d.ts +47 -0
- package/dist/tools/call-context.d.ts.map +1 -0
- package/dist/tools/call-context.js +15 -0
- package/dist/tools/call-context.js.map +1 -0
- package/dist/tools/codegen-tools.d.ts +4 -0
- package/dist/tools/codegen-tools.d.ts.map +1 -0
- package/dist/tools/codegen-tools.js +131 -0
- package/dist/tools/codegen-tools.js.map +1 -0
- package/dist/tools/credential-tools.d.ts +32 -0
- package/dist/tools/credential-tools.d.ts.map +1 -0
- package/dist/tools/credential-tools.js +65 -0
- package/dist/tools/credential-tools.js.map +1 -0
- package/dist/tools/descriptor.d.ts +52 -0
- package/dist/tools/descriptor.d.ts.map +1 -0
- package/dist/tools/descriptor.js +2 -0
- package/dist/tools/descriptor.js.map +1 -0
- package/dist/tools/diagnostic-tools.d.ts +3 -0
- package/dist/tools/diagnostic-tools.d.ts.map +1 -0
- package/dist/tools/diagnostic-tools.js +128 -0
- package/dist/tools/diagnostic-tools.js.map +1 -0
- package/dist/tools/gateway-tools.d.ts +6 -0
- package/dist/tools/gateway-tools.d.ts.map +1 -0
- package/dist/tools/gateway-tools.js +381 -0
- package/dist/tools/gateway-tools.js.map +1 -0
- package/dist/tools/hash-tools.d.ts +5 -0
- package/dist/tools/hash-tools.d.ts.map +1 -0
- package/dist/tools/hash-tools.js +238 -0
- package/dist/tools/hash-tools.js.map +1 -0
- package/dist/tools/knowledge-tools.d.ts +7 -0
- package/dist/tools/knowledge-tools.d.ts.map +1 -0
- package/dist/tools/knowledge-tools.js +247 -0
- package/dist/tools/knowledge-tools.js.map +1 -0
- package/dist/tools/onboarding-checklist.d.ts +3 -0
- package/dist/tools/onboarding-checklist.d.ts.map +1 -0
- package/dist/tools/onboarding-checklist.js +141 -0
- package/dist/tools/onboarding-checklist.js.map +1 -0
- package/dist/tools/register.d.ts +60 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +145 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +88 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +297 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/validation/payload-validator.d.ts +29 -0
- package/dist/validation/payload-validator.d.ts.map +1 -0
- package/dist/validation/payload-validator.js +79 -0
- package/dist/validation/payload-validator.js.map +1 -0
- package/dist/validation/rules/amount.d.ts +3 -0
- package/dist/validation/rules/amount.d.ts.map +1 -0
- package/dist/validation/rules/amount.js +77 -0
- package/dist/validation/rules/amount.js.map +1 -0
- package/dist/validation/rules/bill-reference.d.ts +10 -0
- package/dist/validation/rules/bill-reference.d.ts.map +1 -0
- package/dist/validation/rules/bill-reference.js +34 -0
- package/dist/validation/rules/bill-reference.js.map +1 -0
- package/dist/validation/rules/cnic.d.ts +3 -0
- package/dist/validation/rules/cnic.d.ts.map +1 -0
- package/dist/validation/rules/cnic.js +42 -0
- package/dist/validation/rules/cnic.js.map +1 -0
- package/dist/validation/rules/constants.d.ts +9 -0
- package/dist/validation/rules/constants.d.ts.map +1 -0
- package/dist/validation/rules/constants.js +28 -0
- package/dist/validation/rules/constants.js.map +1 -0
- package/dist/validation/rules/constraints.d.ts +3 -0
- package/dist/validation/rules/constraints.d.ts.map +1 -0
- package/dist/validation/rules/constraints.js +113 -0
- package/dist/validation/rules/constraints.js.map +1 -0
- package/dist/validation/rules/datetime.d.ts +3 -0
- package/dist/validation/rules/datetime.d.ts.map +1 -0
- package/dist/validation/rules/datetime.js +49 -0
- package/dist/validation/rules/datetime.js.map +1 -0
- package/dist/validation/rules/empty-string.d.ts +13 -0
- package/dist/validation/rules/empty-string.d.ts.map +1 -0
- package/dist/validation/rules/empty-string.js +32 -0
- package/dist/validation/rules/empty-string.js.map +1 -0
- package/dist/validation/rules/expiry.d.ts +3 -0
- package/dist/validation/rules/expiry.d.ts.map +1 -0
- package/dist/validation/rules/expiry.js +52 -0
- package/dist/validation/rules/expiry.js.map +1 -0
- package/dist/validation/rules/msisdn.d.ts +3 -0
- package/dist/validation/rules/msisdn.d.ts.map +1 -0
- package/dist/validation/rules/msisdn.js +45 -0
- package/dist/validation/rules/msisdn.js.map +1 -0
- package/dist/validation/rules/presence.d.ts +3 -0
- package/dist/validation/rules/presence.d.ts.map +1 -0
- package/dist/validation/rules/presence.js +90 -0
- package/dist/validation/rules/presence.js.map +1 -0
- package/dist/validation/rules/return-url.d.ts +14 -0
- package/dist/validation/rules/return-url.d.ts.map +1 -0
- package/dist/validation/rules/return-url.js +58 -0
- package/dist/validation/rules/return-url.js.map +1 -0
- package/dist/validation/rules/tool-argument.d.ts +16 -0
- package/dist/validation/rules/tool-argument.d.ts.map +1 -0
- package/dist/validation/rules/tool-argument.js +38 -0
- package/dist/validation/rules/tool-argument.js.map +1 -0
- package/dist/validation/rules/txn-ref.d.ts +3 -0
- package/dist/validation/rules/txn-ref.d.ts.map +1 -0
- package/dist/validation/rules/txn-ref.js +47 -0
- package/dist/validation/rules/txn-ref.js.map +1 -0
- package/dist/validation/rules/unknown-fields.d.ts +10 -0
- package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
- package/dist/validation/rules/unknown-fields.js +29 -0
- package/dist/validation/rules/unknown-fields.js.map +1 -0
- package/dist/validation/types.d.ts +36 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +12 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/version.d.ts +23 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/knowledge/diagnostics/symptoms.json +321 -0
- package/knowledge/docs/bnpl-guide.md +77 -0
- package/knowledge/docs/card-page-redirection.md +67 -0
- package/knowledge/docs/card-refund.md +91 -0
- package/knowledge/docs/hmac-sha256-calculation.md +72 -0
- package/knowledge/docs/index.json +189 -0
- package/knowledge/docs/ipn-implementation.md +89 -0
- package/knowledge/docs/mwallet-recurring.md +117 -0
- package/knowledge/docs/mwallet-refund.md +65 -0
- package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
- package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
- package/knowledge/docs/portal-guide.md +45 -0
- package/knowledge/docs/shopify-guide.md +74 -0
- package/knowledge/docs/status-inquiry-2025-26.md +32 -0
- package/knowledge/docs/status-inquiry.md +111 -0
- package/knowledge/docs/wordpress-guide.md +49 -0
- package/knowledge/flow.schema.json +390 -0
- package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
- package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
- package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
- package/knowledge/flows/refund-bnpl.json +105 -0
- package/knowledge/flows/refund-card-v1.1.json +112 -0
- package/knowledge/flows/refund-card-v2.0.json +121 -0
- package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
- package/knowledge/flows/status-inquiry-v1.1.json +102 -0
- package/knowledge/flows/status-inquiry-v2.0.json +103 -0
- package/knowledge/flows/token-delete-v1.json +85 -0
- package/knowledge/flows/token-inquiry-v1.json +85 -0
- package/knowledge/flows/wallet-linking-portal.json +103 -0
- package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
- package/knowledge/templates/node/ipn-handler.tmpl +108 -0
- package/knowledge/templates/node/rest-client.tmpl +197 -0
- package/knowledge/templates/node/wallet-linking.tmpl +147 -0
- package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
- package/knowledge/templates/php/ipn-handler.tmpl +105 -0
- package/knowledge/templates/php/rest-client.tmpl +191 -0
- package/knowledge/templates/php/wallet-linking.tmpl +137 -0
- package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
- package/knowledge/templates/python/ipn-handler.tmpl +110 -0
- package/knowledge/templates/python/rest-client.tmpl +179 -0
- package/knowledge/templates/python/wallet-linking.tmpl +133 -0
- package/package.json +84 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { PORTAL_URLS } from '../catalogue/endpoints.js';
|
|
3
|
+
import { citations, safeHandler, toolResult } from './tool-kit.js';
|
|
4
|
+
/**
|
|
5
|
+
* The onboarding sequence a resident engineer walks every merchant through.
|
|
6
|
+
*
|
|
7
|
+
* Assembled from the "Create a Sandbox Account", "Mandatory API Integrations"
|
|
8
|
+
* and "Testing" sections that repeat across the guides, plus the platform
|
|
9
|
+
* specifics from the WooCommerce and Shopify guides.
|
|
10
|
+
*/
|
|
11
|
+
const PLATFORMS = ['custom', 'woocommerce', 'shopify'];
|
|
12
|
+
/** Screenshot evidence JazzCash asks for, from the card redirection guide. */
|
|
13
|
+
const TEST_EVIDENCE = [
|
|
14
|
+
'Merchant checkout page',
|
|
15
|
+
'JazzCash landing page',
|
|
16
|
+
'Payment method selection',
|
|
17
|
+
'Payment step',
|
|
18
|
+
'Payment response received on the merchant Callback URL',
|
|
19
|
+
'Order status in the merchant admin panel',
|
|
20
|
+
];
|
|
21
|
+
function accountSteps(flow) {
|
|
22
|
+
const steps = [
|
|
23
|
+
`Sign up for a sandbox account at ${PORTAL_URLS.sandboxSignup}.`,
|
|
24
|
+
'Send your Merchant ID to JazzCash and ask them to enable the payment options you need. Until they do, the method will not appear.',
|
|
25
|
+
'In the sandbox portal, open Integration → Credentials and record the Merchant ID, Password and Integrity Salt.',
|
|
26
|
+
'Enter your Return URL / Callback URL in the same screen. It becomes part of your merchant profile and must then be used unchanged in every request.',
|
|
27
|
+
'Enter your IPN URL in the IPN field.',
|
|
28
|
+
// Assumption A5, docs/mcp/JAZZCASH-CLARIFICATIONS.md item 6. The guides
|
|
29
|
+
// instruct merchants to test with "the sandbox testing numbers" and then
|
|
30
|
+
// publish none of them, so the first sandbox transaction fails for a reason
|
|
31
|
+
// no document explains. Stated here, in the steps every flow shares, rather
|
|
32
|
+
// than only in the WooCommerce path where it used to live: a merchant who
|
|
33
|
+
// learns this after the failure has already spent the afternoon on it.
|
|
34
|
+
'Ask JazzCash for the sandbox test MSISDNs and CNICs, and for any that deliberately trigger failure codes. They are NOT published in any guide, and no sandbox transaction can be completed without them. Request them at the same time as your credentials, because nothing else in this checklist can be verified until they arrive.',
|
|
35
|
+
];
|
|
36
|
+
if (flow.product === 'refund' || flow.companionFlows.some((id) => id.startsWith('refund'))) {
|
|
37
|
+
steps.push('Save your Merchant MPIN in the merchant portal. Refunds fail until it is stored there, not merely sent in the request.');
|
|
38
|
+
}
|
|
39
|
+
if (flow.id === 'bnpl-page-redirection-v1.1' || flow.id === 'refund-bnpl') {
|
|
40
|
+
steps.push('BNPL is tested with PRODUCTION credentials, not sandbox. Every BNPL test is a real transaction: use the smallest possible amount and refund it afterwards.');
|
|
41
|
+
}
|
|
42
|
+
return steps;
|
|
43
|
+
}
|
|
44
|
+
function platformSteps(platform) {
|
|
45
|
+
if (platform === 'woocommerce') {
|
|
46
|
+
return [
|
|
47
|
+
'Confirm WooCommerce is installed and active.',
|
|
48
|
+
'Obtain the JazzCash plugin .zip from JazzCash, upload it under Plugins → Add New → Upload, and activate it.',
|
|
49
|
+
'Enter your credentials under WooCommerce → Settings → Payments → JazzCash → Manage, and save.',
|
|
50
|
+
'Register Return URL `{yourBaseURL}/wc-api/result/` in the portal Credentials tab. The trailing slash matters.',
|
|
51
|
+
'Register IPN URL `{yourBaseURL}/jazzcash_ipn_v2` in the portal Credentials tab.',
|
|
52
|
+
'Add two test products, one at PKR 10 and one at PKR 1, for card and wallet testing.',
|
|
53
|
+
'Confirm you have the sandbox test numbers from JazzCash before testing — see the account steps above; they are published in no guide.',
|
|
54
|
+
'Process refunds from the JazzCash Transaction tab.',
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
if (platform === 'shopify') {
|
|
58
|
+
return [
|
|
59
|
+
'Settle, capture or refund every pending transaction in the old JazzCash app, and export any reports you need.',
|
|
60
|
+
'Shopify Admin → Settings → Payments → the existing JazzCash method → Manage → Deactivate. Do NOT uninstall the old app yet.',
|
|
61
|
+
'Install the new app from https://apps.shopify.com/jazzcash and approve the permissions.',
|
|
62
|
+
'Enter Merchant ID, Integrity Salt and Password on the onboarding screen and save.',
|
|
63
|
+
'Settings → Payments → the new JazzCash method → Activate.',
|
|
64
|
+
'Open App, confirm the credentials, and check the Transactions tab.',
|
|
65
|
+
'Place a small-value test order and confirm redirection, status update and that the order is marked Paid.',
|
|
66
|
+
'Only once everything is settled and tested, uninstall the old app from Settings → Apps and Sales Channels.',
|
|
67
|
+
'Save the Merchant MPIN in the merchant portal before attempting a refund from the order details page.',
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
return [
|
|
71
|
+
'Generate pp_SecureHash server-side. Never compute it in browser JavaScript: the Integrity Salt is the HMAC key and would be published in your page source.',
|
|
72
|
+
'Build the payload with jazzcash_build_transaction_parameters so constants, timestamps, minor units and the hash are all correct by construction.',
|
|
73
|
+
'Implement the Status Inquiry API. It is mandatory, and it is how you resolve any transaction whose outcome you did not see.',
|
|
74
|
+
'Implement an IPN listener. It is mandatory. Verify pp_SecureHash before acting, make it idempotent against the documented 2 retries, and respond with pp_ResponseCode "000" within 60 seconds.',
|
|
75
|
+
'Implement the Refund API if you need refunds. It is optional.',
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
export const registerOnboardingChecklist = (server, deps) => {
|
|
79
|
+
server.registerTool('jazzcash_get_onboarding_checklist', {
|
|
80
|
+
title: 'Get the JazzCash onboarding checklist',
|
|
81
|
+
description: 'The full setup sequence for a flow: sandbox account, credentials, URL registration, mandatory companion APIs, the test evidence JazzCash requires, and go-live steps. Platform-specific steps for WooCommerce and Shopify.',
|
|
82
|
+
inputSchema: {
|
|
83
|
+
flowId: z.string().describe('Flow you are integrating, e.g. "card-page-redirection-v1.1".'),
|
|
84
|
+
platform: z
|
|
85
|
+
.enum(PLATFORMS)
|
|
86
|
+
.optional()
|
|
87
|
+
.describe('"woocommerce" or "shopify" for plugin steps; "custom" (default) for a bespoke integration.'),
|
|
88
|
+
},
|
|
89
|
+
}, safeHandler(deps, 'jazzcash_get_onboarding_checklist', ({ flowId, platform }) => {
|
|
90
|
+
const flow = deps.catalogue.get(flowId);
|
|
91
|
+
const resolvedPlatform = platform ?? 'custom';
|
|
92
|
+
const account = accountSteps(flow);
|
|
93
|
+
const implementation = platformSteps(resolvedPlatform);
|
|
94
|
+
const mandatory = flow.companionFlows.length > 0 ? flow.companionFlows : ['status-inquiry-v1.1'];
|
|
95
|
+
const numbered = (steps, offset = 0) => steps.map((step, index) => `${String(index + 1 + offset)}. ${step}`).join('\n');
|
|
96
|
+
const text = [
|
|
97
|
+
`# Onboarding checklist — ${flow.title}`,
|
|
98
|
+
resolvedPlatform === 'custom' ? '' : `Platform: ${resolvedPlatform}`,
|
|
99
|
+
'',
|
|
100
|
+
'## 1. Account and credentials',
|
|
101
|
+
numbered(account),
|
|
102
|
+
'',
|
|
103
|
+
`## 2. Implementation (${resolvedPlatform})`,
|
|
104
|
+
numbered(implementation),
|
|
105
|
+
'',
|
|
106
|
+
'## 3. Mandatory companion integrations',
|
|
107
|
+
'The guides mark these as mandatory, not optional:',
|
|
108
|
+
mandatory.map((id) => `- ${id}`).join('\n'),
|
|
109
|
+
'- An IPN listener (see jazzcash://docs/ipn-implementation)',
|
|
110
|
+
'',
|
|
111
|
+
'## 4. Test evidence JazzCash requires',
|
|
112
|
+
'This step needs the sandbox test MSISDNs and CNICs, which no guide publishes. If you have not received them from JazzCash yet, stop here and ask: the transactions below cannot be completed without them.',
|
|
113
|
+
'Perform test transactions for each payment method you have enabled — mobile account, voucher and credit/debit card — and capture, for each:',
|
|
114
|
+
TEST_EVIDENCE.map((item) => `- ${item}`).join('\n'),
|
|
115
|
+
'Paste the screenshots into the template JazzCash supplied and reply on the same email thread.',
|
|
116
|
+
'',
|
|
117
|
+
'## 5. Before go-live',
|
|
118
|
+
'1. Confirm pp_ReturnURL registered in the portal is byte-identical to the one you send.',
|
|
119
|
+
'2. Confirm pp_Amount is multiplied by 100 everywhere, including refunds.',
|
|
120
|
+
'3. Confirm pp_TxnRefNo is unique per transaction. A timestamp alone collides whenever two orders are placed in the same second, so append random characters inside the 20-character limit.',
|
|
121
|
+
'4. Confirm your IPN listener verifies pp_SecureHash and is idempotent.',
|
|
122
|
+
'5. Confirm the Integrity Salt exists only on your server, never in client-side code or version control.',
|
|
123
|
+
'6. Swap sandbox credentials for production credentials. The endpoint does not change, so this credential swap IS the go-live switch.',
|
|
124
|
+
'7. Run one small live transaction and refund it.',
|
|
125
|
+
citations(flow.docRefs),
|
|
126
|
+
]
|
|
127
|
+
.filter((line) => line !== '')
|
|
128
|
+
.join('\n');
|
|
129
|
+
return toolResult(text, {
|
|
130
|
+
structuredContent: {
|
|
131
|
+
flowId: flow.id,
|
|
132
|
+
platform: resolvedPlatform,
|
|
133
|
+
accountSteps: account,
|
|
134
|
+
implementationSteps: implementation,
|
|
135
|
+
mandatoryCompanions: mandatory,
|
|
136
|
+
testEvidence: TEST_EVIDENCE,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
}));
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=onboarding-checklist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-checklist.js","sourceRoot":"","sources":["../../src/tools/onboarding-checklist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Registrar } from '../registry.js';
|
|
2
|
+
import { type ToolFacts } from './descriptor.js';
|
|
3
|
+
/**
|
|
4
|
+
* The tool surface, described once.
|
|
5
|
+
*
|
|
6
|
+
* Each tool lives in its own module and exports a single registrar. Describing
|
|
7
|
+
* them here keeps `createServer` from growing into a god object and makes the
|
|
8
|
+
* tool surface auditable at a glance.
|
|
9
|
+
*
|
|
10
|
+
* The four credential-requiring descriptors are imported from
|
|
11
|
+
* `./credential-tools.js` rather than declared here, and this module re-exports
|
|
12
|
+
* that list unchanged. The direction matters: a consumer that needs only those
|
|
13
|
+
* four — the published connector — imports the narrow module and never reaches
|
|
14
|
+
* this one, so it never pulls the corpus loader, the search index, the code
|
|
15
|
+
* generators or the diagnostics into its build. A consumer that needs the whole
|
|
16
|
+
* surface imports this module and gets both halves in the order below.
|
|
17
|
+
*/
|
|
18
|
+
export type { CoreToolDescriptor, ToolFacts, ToolGroup } from './descriptor.js';
|
|
19
|
+
export { CREDENTIAL_TOOLS } from './credential-tools.js';
|
|
20
|
+
export interface ToolDescriptor extends ToolFacts {
|
|
21
|
+
readonly registrar: Registrar;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Every tool, with the two facts no consumer can derive for itself.
|
|
25
|
+
*
|
|
26
|
+
* `requiresCredentials` is an explicit per-tool flag rather than a property of
|
|
27
|
+
* `group`, because the two genuinely disagree and always will. Inferring the
|
|
28
|
+
* split from the group would put `jazzcash_build_transaction_parameters` — which
|
|
29
|
+
* sits in the hash group but resolves a credential profile unconditionally, and
|
|
30
|
+
* signs a payload with the merchant's Integrity Salt — on a public hosted
|
|
31
|
+
* endpoint, where it would either fail on every call or run against whatever
|
|
32
|
+
* credentials that host happens to hold. The same inference would withhold
|
|
33
|
+
* `jazzcash_verify_ipn_notification` from the hosted tier although it takes its
|
|
34
|
+
* salt as a call argument and needs no configured credential at all.
|
|
35
|
+
*
|
|
36
|
+
* The flag says only what the handler does: a tool is marked `true` when it
|
|
37
|
+
* resolves a `CredentialProfile` on every path (directly through
|
|
38
|
+
* `deps.credentials.get`, or through `guardGatewayCall`), and `false` when the
|
|
39
|
+
* value can be supplied per call or is optional enrichment guarded by
|
|
40
|
+
* `deps.credentials.has`. Determined by reading each handler; a tool whose
|
|
41
|
+
* handler starts resolving credentials must move to `./credential-tools.js` in
|
|
42
|
+
* the same change. `tests/tools/register.test.ts` fails on a tool with no
|
|
43
|
+
* descriptor at all, on a `true` flag declared outside that module, and on a
|
|
44
|
+
* descriptor duplicated rather than shared between the two lists. A handler that
|
|
45
|
+
* cannot be typed as a `CoreRegistrar` is caught earlier still, by the compiler,
|
|
46
|
+
* and `scripts/closure.mjs` fails the build if what it reaches widens.
|
|
47
|
+
*
|
|
48
|
+
* Listed in group order, so `ALL_TOOLS` keeps the registration order it had
|
|
49
|
+
* before the descriptors existed.
|
|
50
|
+
*/
|
|
51
|
+
export declare const TOOL_DESCRIPTORS: readonly ToolDescriptor[];
|
|
52
|
+
export declare const KNOWLEDGE_TOOLS: readonly Registrar[];
|
|
53
|
+
export declare const HASH_TOOLS: readonly Registrar[];
|
|
54
|
+
export declare const CODEGEN_TOOLS: readonly Registrar[];
|
|
55
|
+
export declare const GATEWAY_TOOLS: readonly Registrar[];
|
|
56
|
+
export declare const DIAGNOSTIC_TOOLS: readonly Registrar[];
|
|
57
|
+
export declare const ALL_TOOLS: readonly Registrar[];
|
|
58
|
+
/** Tools that need no configured credential, and are safe to serve from a host that holds none. */
|
|
59
|
+
export declare const CREDENTIAL_FREE_TOOLS: readonly ToolDescriptor[];
|
|
60
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQhD,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,iBAAiB,CAAC;AAajE;;;;;;;;;;;;;;GAcG;AAEH,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,cAAc,EA+FrD,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,SAAS,SAAS,EAAmC,CAAC;AAEpF,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAA8B,CAAC;AAE1E,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAAiC,CAAC;AAEhF,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAAiC,CAAC;AAEhF,eAAO,MAAM,gBAAgB,EAAE,SAAS,SAAS,EAAqC,CAAC;AAEvF,eAAO,MAAM,SAAS,EAAE,SAAS,SAAS,EAA+D,CAAC;AAE1G,mGAAmG;AACnG,eAAO,MAAM,qBAAqB,EAAE,SAAS,cAAc,EAE1D,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { registerGenerateIntegrationCode, registerGenerateIpnHandler } from './codegen-tools.js';
|
|
2
|
+
import { BUILD_CHECKOUT_FORM, BUILD_TRANSACTION_PARAMETERS, RUN_SANDBOX_SMOKE_TEST, SEND_GATEWAY_REQUEST, } from './credential-tools.js';
|
|
3
|
+
import {} from './descriptor.js';
|
|
4
|
+
import { registerDiagnoseIntegrationIssue } from './diagnostic-tools.js';
|
|
5
|
+
import { registerVerifyIpnNotification } from './gateway-tools.js';
|
|
6
|
+
import { registerBuildSecureHash, registerValidatePayload, registerVerifySecureHash } from './hash-tools.js';
|
|
7
|
+
import { registerExplainResponseCode, registerGetDocSection, registerGetIntegrationFlow, registerListIntegrationFlows, registerSearchDocs, } from './knowledge-tools.js';
|
|
8
|
+
import { registerOnboardingChecklist } from './onboarding-checklist.js';
|
|
9
|
+
export { CREDENTIAL_TOOLS } from './credential-tools.js';
|
|
10
|
+
/**
|
|
11
|
+
* Every tool, with the two facts no consumer can derive for itself.
|
|
12
|
+
*
|
|
13
|
+
* `requiresCredentials` is an explicit per-tool flag rather than a property of
|
|
14
|
+
* `group`, because the two genuinely disagree and always will. Inferring the
|
|
15
|
+
* split from the group would put `jazzcash_build_transaction_parameters` — which
|
|
16
|
+
* sits in the hash group but resolves a credential profile unconditionally, and
|
|
17
|
+
* signs a payload with the merchant's Integrity Salt — on a public hosted
|
|
18
|
+
* endpoint, where it would either fail on every call or run against whatever
|
|
19
|
+
* credentials that host happens to hold. The same inference would withhold
|
|
20
|
+
* `jazzcash_verify_ipn_notification` from the hosted tier although it takes its
|
|
21
|
+
* salt as a call argument and needs no configured credential at all.
|
|
22
|
+
*
|
|
23
|
+
* The flag says only what the handler does: a tool is marked `true` when it
|
|
24
|
+
* resolves a `CredentialProfile` on every path (directly through
|
|
25
|
+
* `deps.credentials.get`, or through `guardGatewayCall`), and `false` when the
|
|
26
|
+
* value can be supplied per call or is optional enrichment guarded by
|
|
27
|
+
* `deps.credentials.has`. Determined by reading each handler; a tool whose
|
|
28
|
+
* handler starts resolving credentials must move to `./credential-tools.js` in
|
|
29
|
+
* the same change. `tests/tools/register.test.ts` fails on a tool with no
|
|
30
|
+
* descriptor at all, on a `true` flag declared outside that module, and on a
|
|
31
|
+
* descriptor duplicated rather than shared between the two lists. A handler that
|
|
32
|
+
* cannot be typed as a `CoreRegistrar` is caught earlier still, by the compiler,
|
|
33
|
+
* and `scripts/closure.mjs` fails the build if what it reaches widens.
|
|
34
|
+
*
|
|
35
|
+
* Listed in group order, so `ALL_TOOLS` keeps the registration order it had
|
|
36
|
+
* before the descriptors existed.
|
|
37
|
+
*/
|
|
38
|
+
export const TOOL_DESCRIPTORS = [
|
|
39
|
+
{
|
|
40
|
+
name: 'jazzcash_list_integration_flows',
|
|
41
|
+
registrar: registerListIntegrationFlows,
|
|
42
|
+
group: 'knowledge',
|
|
43
|
+
requiresCredentials: false,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'jazzcash_get_integration_flow',
|
|
47
|
+
registrar: registerGetIntegrationFlow,
|
|
48
|
+
group: 'knowledge',
|
|
49
|
+
requiresCredentials: false,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'jazzcash_search_docs',
|
|
53
|
+
registrar: registerSearchDocs,
|
|
54
|
+
group: 'knowledge',
|
|
55
|
+
requiresCredentials: false,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'jazzcash_get_doc_section',
|
|
59
|
+
registrar: registerGetDocSection,
|
|
60
|
+
group: 'knowledge',
|
|
61
|
+
requiresCredentials: false,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
// The documented JazzCash code tables, keyed by JazzCash field names.
|
|
65
|
+
name: 'jazzcash_explain_response_code',
|
|
66
|
+
registrar: registerExplainResponseCode,
|
|
67
|
+
group: 'knowledge',
|
|
68
|
+
requiresCredentials: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
// JazzCash portal steps, the evidence JazzCash asks for, and go-live checks
|
|
72
|
+
// written against `pp_` field names.
|
|
73
|
+
name: 'jazzcash_get_onboarding_checklist',
|
|
74
|
+
registrar: registerOnboardingChecklist,
|
|
75
|
+
group: 'knowledge',
|
|
76
|
+
requiresCredentials: false,
|
|
77
|
+
},
|
|
78
|
+
BUILD_TRANSACTION_PARAMETERS,
|
|
79
|
+
{
|
|
80
|
+
// `resolveIntegritySalt` prefers an explicitly supplied salt, so a caller
|
|
81
|
+
// debugging their own value never touches the credential store.
|
|
82
|
+
name: 'jazzcash_build_secure_hash',
|
|
83
|
+
registrar: registerBuildSecureHash,
|
|
84
|
+
group: 'hash',
|
|
85
|
+
requiresCredentials: false,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'jazzcash_verify_secure_hash',
|
|
89
|
+
registrar: registerVerifySecureHash,
|
|
90
|
+
group: 'hash',
|
|
91
|
+
requiresCredentials: false,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
// Reads the registered Return URL only when a profile exists
|
|
95
|
+
// (`deps.credentials.has`), and validates the payload either way.
|
|
96
|
+
name: 'jazzcash_validate_payload',
|
|
97
|
+
registrar: registerValidatePayload,
|
|
98
|
+
group: 'hash',
|
|
99
|
+
requiresCredentials: false,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'jazzcash_generate_integration_code',
|
|
103
|
+
registrar: registerGenerateIntegrationCode,
|
|
104
|
+
group: 'codegen',
|
|
105
|
+
requiresCredentials: false,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
// Generates from the flow specification, but defaults to a JazzCash flow and
|
|
109
|
+
// appends JazzCash portal registration steps to every result.
|
|
110
|
+
name: 'jazzcash_generate_ipn_handler',
|
|
111
|
+
registrar: registerGenerateIpnHandler,
|
|
112
|
+
group: 'codegen',
|
|
113
|
+
requiresCredentials: false,
|
|
114
|
+
},
|
|
115
|
+
SEND_GATEWAY_REQUEST,
|
|
116
|
+
RUN_SANDBOX_SMOKE_TEST,
|
|
117
|
+
BUILD_CHECKOUT_FORM,
|
|
118
|
+
{
|
|
119
|
+
// Takes its salt as a call argument, and only falls back to the configured
|
|
120
|
+
// profile when none is supplied. In the gateway group because it answers an
|
|
121
|
+
// inbound notification, not because it holds a credential.
|
|
122
|
+
name: 'jazzcash_verify_ipn_notification',
|
|
123
|
+
registrar: registerVerifyIpnNotification,
|
|
124
|
+
group: 'gateway',
|
|
125
|
+
requiresCredentials: false,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'jazzcash_diagnose_integration_issue',
|
|
129
|
+
registrar: registerDiagnoseIntegrationIssue,
|
|
130
|
+
group: 'diagnostics',
|
|
131
|
+
requiresCredentials: false,
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
function registrarsInGroup(group) {
|
|
135
|
+
return TOOL_DESCRIPTORS.filter((descriptor) => descriptor.group === group).map((descriptor) => descriptor.registrar);
|
|
136
|
+
}
|
|
137
|
+
export const KNOWLEDGE_TOOLS = registrarsInGroup('knowledge');
|
|
138
|
+
export const HASH_TOOLS = registrarsInGroup('hash');
|
|
139
|
+
export const CODEGEN_TOOLS = registrarsInGroup('codegen');
|
|
140
|
+
export const GATEWAY_TOOLS = registrarsInGroup('gateway');
|
|
141
|
+
export const DIAGNOSTIC_TOOLS = registrarsInGroup('diagnostics');
|
|
142
|
+
export const ALL_TOOLS = TOOL_DESCRIPTORS.map((descriptor) => descriptor.registrar);
|
|
143
|
+
/** Tools that need no configured credential, and are safe to serve from a host that holds none. */
|
|
144
|
+
export const CREDENTIAL_FREE_TOOLS = TOOL_DESCRIPTORS.filter((descriptor) => !descriptor.requiresCredentials);
|
|
145
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { JazzCashEnvironment } from '../config/environment.js';
|
|
3
|
+
import type { CoreDependencies } from '../core/dependencies.js';
|
|
4
|
+
import type { CallContext } from './call-context.js';
|
|
5
|
+
/**
|
|
6
|
+
* Shared plumbing for tool handlers.
|
|
7
|
+
*
|
|
8
|
+
* Three invariants are enforced here rather than repeated in every tool:
|
|
9
|
+
*
|
|
10
|
+
* - A thrown error becomes an `isError` result rather than escaping across the
|
|
11
|
+
* protocol boundary, so a merchant sees an explanation instead of a
|
|
12
|
+
* transport-level failure.
|
|
13
|
+
* - Every string a tool returns is scrubbed of known credential literals and of
|
|
14
|
+
* the values of known credential fields. A tool result is transcript content;
|
|
15
|
+
* a password that reaches it is disclosed. Text and `structuredContent` are
|
|
16
|
+
* scrubbed to the same policy, so no tool can leak through one by embedding a
|
|
17
|
+
* payload in the other.
|
|
18
|
+
* - Every call is given a {@link CallContext}, so a log record can be traced to
|
|
19
|
+
* the call that produced it rather than only to the server as a whole.
|
|
20
|
+
*
|
|
21
|
+
* A fourth rule lives here and the wrapper applies it for every tool that
|
|
22
|
+
* declares which of its arguments carry caller-chosen field names: a parameter
|
|
23
|
+
* the flow marks `neverAcceptAsToolArgument` is refused before the handler runs.
|
|
24
|
+
* See {@link PayloadArgumentDeclaration} for why the declaration has to be
|
|
25
|
+
* written down rather than inferred.
|
|
26
|
+
*/
|
|
27
|
+
export interface ToolTextOptions {
|
|
28
|
+
readonly structuredContent?: Record<string, unknown>;
|
|
29
|
+
readonly isError?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Build a tool result carrying both human-readable text and structured data. */
|
|
32
|
+
export declare function toolResult(text: string, options?: ToolTextOptions): CallToolResult;
|
|
33
|
+
/** Build a failure result, naming the stable error code when there is one. */
|
|
34
|
+
export declare function toolError(error: unknown, secrets?: readonly string[]): CallToolResult;
|
|
35
|
+
/**
|
|
36
|
+
* Which of a tool's arguments carry field names the caller chooses.
|
|
37
|
+
*
|
|
38
|
+
* Declared at registration rather than restated as a branch in the handler
|
|
39
|
+
* body. The wrapper is generic over `Args` and so cannot work the names out for
|
|
40
|
+
* itself — a check that guessed would miss a key it had not been told about and
|
|
41
|
+
* accept a PAN in silence — but a tool that names them turns that guess into a
|
|
42
|
+
* statement, and a tool that names none is opting out visibly rather than by
|
|
43
|
+
* forgetting a line. `flowFrom` names the argument holding the flow id, which
|
|
44
|
+
* chooses the explanatory sentence only; the list of refused names is the
|
|
45
|
+
* catalogue-wide union either way.
|
|
46
|
+
*/
|
|
47
|
+
export interface PayloadArgumentDeclaration<Args> {
|
|
48
|
+
/** Arguments whose keys are the caller's, e.g. `extras`, `parameters`. */
|
|
49
|
+
readonly payloadArguments: readonly (keyof Args & string)[];
|
|
50
|
+
/** Argument naming the flow, for tools that take one. */
|
|
51
|
+
readonly flowFrom?: keyof Args & string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Wrap a handler so failures surface as tool errors and secrets never leak.
|
|
55
|
+
*
|
|
56
|
+
* Redaction covers every configured profile, not only the one in play, because a
|
|
57
|
+
* caller can pass an explicit salt for one environment while another is active.
|
|
58
|
+
*
|
|
59
|
+
* The handler receives a {@link CallContext} built for this invocation. It is
|
|
60
|
+
* built from `deps` rather than from the SDK's `extra` argument, and the second
|
|
61
|
+
* parameter below is the reason that distinction has to be written down.
|
|
62
|
+
*
|
|
63
|
+
* A `declaration` makes the wrapper refuse forbidden arguments before the
|
|
64
|
+
* handler runs at all, so the flagged value is never read, built into a payload
|
|
65
|
+
* or written to a log. The refusal is returned through the same scrubbing path
|
|
66
|
+
* as any other result.
|
|
67
|
+
*/
|
|
68
|
+
export declare function safeHandler<Args>(deps: CoreDependencies, toolName: string, handler: (args: Args, context: CallContext) => CallToolResult | Promise<CallToolResult>, declaration?: PayloadArgumentDeclaration<Args>): (args: Args, extra?: unknown) => Promise<CallToolResult>;
|
|
69
|
+
/** Resolve the environment a tool should act in, defaulting to the configured one. */
|
|
70
|
+
export declare function resolveEnvironment(deps: CoreDependencies, requested: JazzCashEnvironment | undefined): JazzCashEnvironment;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve the Integrity Salt for a hash operation.
|
|
73
|
+
*
|
|
74
|
+
* An explicit salt is accepted because a merchant debugging a mismatch usually
|
|
75
|
+
* has the value in front of them and may not have configured the server yet.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveIntegritySalt(deps: CoreDependencies, explicitSalt: string | undefined, environment: JazzCashEnvironment): {
|
|
78
|
+
salt: string;
|
|
79
|
+
source: string;
|
|
80
|
+
};
|
|
81
|
+
/** Render a bullet list, or a placeholder when there is nothing to list. */
|
|
82
|
+
export declare function bulletList(items: readonly string[], empty?: string): string;
|
|
83
|
+
/** Render a citation line for a set of documentation references. */
|
|
84
|
+
export declare function citations(refs: readonly {
|
|
85
|
+
docId: string;
|
|
86
|
+
sectionId?: string | undefined;
|
|
87
|
+
}[]): string;
|
|
88
|
+
//# sourceMappingURL=tool-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-kit.d.ts","sourceRoot":"","sources":["../../src/tools/tool-kit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAKzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAMtF;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,SAAS,MAAM,EAAO,GAAG,cAAc,CAQzF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,0BAA0B,CAAC,IAAI;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5D,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAC9B,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,KAAK,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,EACvF,WAAW,CAAC,EAAE,0BAA0B,CAAC,IAAI,CAAC,GAC7C,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,cAAc,CAAC,CA4C1D;AAkOD,sFAAsF;AACtF,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,mBAAmB,GAAG,SAAS,GACzC,mBAAmB,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,gBAAgB,EACtB,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,mBAAmB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAMlC;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAW,GAAG,MAAM,CAE7E;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EAAE,GAAG,MAAM,CAUpG"}
|