@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,24 @@
|
|
|
1
|
+
import { type CorpusSource } from '../knowledge/source.js';
|
|
2
|
+
import type { Language, TemplateKind, TemplateValues } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Substitute `{{NAME}}` placeholders.
|
|
5
|
+
*
|
|
6
|
+
* A placeholder the caller did not supply is an error rather than an empty
|
|
7
|
+
* string: a silently blank credential or endpoint in generated payment code is
|
|
8
|
+
* far worse than a failed generation.
|
|
9
|
+
*/
|
|
10
|
+
export declare function render(template: string, values: TemplateValues): string;
|
|
11
|
+
/** Placeholder names a template requires. Used to verify templates in tests. */
|
|
12
|
+
export declare function requiredPlaceholders(template: string): readonly string[];
|
|
13
|
+
/**
|
|
14
|
+
* Read `{language}/{kind}.tmpl` from the template source, `knowledge/templates/`
|
|
15
|
+
* by default.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately uncached, and the source is consulted on every call. The
|
|
18
|
+
* alternative — a module-level `Map` — is global mutable state with no
|
|
19
|
+
* invalidation, which means an edited template is served stale until the process
|
|
20
|
+
* restarts. Twelve templates of a few kilobytes each, read once per generation,
|
|
21
|
+
* is not a cost worth that.
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadTemplate(language: Language, kind: TemplateKind, templates?: CorpusSource | string): string;
|
|
24
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/codegen/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAazE;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAmBvE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAExE;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,YAAY,GAAG,MAAmC,GAC5D,MAAM,CAYR"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { JazzCashConfigError } from '../errors.js';
|
|
2
|
+
import { toCorpusSource } from '../knowledge/source.js';
|
|
3
|
+
import { knowledgePath } from '../paths.js';
|
|
4
|
+
/**
|
|
5
|
+
* Minimal, escaping-aware template renderer.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately not an expression evaluator. A template can substitute named
|
|
8
|
+
* values and nothing else, so a template cannot execute logic and a malformed
|
|
9
|
+
* template cannot silently emit something surprising into code that will handle
|
|
10
|
+
* money.
|
|
11
|
+
*/
|
|
12
|
+
const PLACEHOLDER = /\{\{([A-Z0-9_]+)\}\}/g;
|
|
13
|
+
/**
|
|
14
|
+
* Substitute `{{NAME}}` placeholders.
|
|
15
|
+
*
|
|
16
|
+
* A placeholder the caller did not supply is an error rather than an empty
|
|
17
|
+
* string: a silently blank credential or endpoint in generated payment code is
|
|
18
|
+
* far worse than a failed generation.
|
|
19
|
+
*/
|
|
20
|
+
export function render(template, values) {
|
|
21
|
+
const missing = new Set();
|
|
22
|
+
const output = template.replace(PLACEHOLDER, (_match, name) => {
|
|
23
|
+
const value = values[name];
|
|
24
|
+
if (value === undefined) {
|
|
25
|
+
missing.add(name);
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
});
|
|
30
|
+
if (missing.size > 0) {
|
|
31
|
+
throw new JazzCashConfigError(`Template is missing value(s) for: ${[...missing].sort().join(', ')}. This is a bug in the generator, not in your configuration.`);
|
|
32
|
+
}
|
|
33
|
+
return output;
|
|
34
|
+
}
|
|
35
|
+
/** Placeholder names a template requires. Used to verify templates in tests. */
|
|
36
|
+
export function requiredPlaceholders(template) {
|
|
37
|
+
return [...new Set([...template.matchAll(PLACEHOLDER)].map((match) => match[1] ?? ''))].sort();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Read `{language}/{kind}.tmpl` from the template source, `knowledge/templates/`
|
|
41
|
+
* by default.
|
|
42
|
+
*
|
|
43
|
+
* Deliberately uncached, and the source is consulted on every call. The
|
|
44
|
+
* alternative — a module-level `Map` — is global mutable state with no
|
|
45
|
+
* invalidation, which means an edited template is served stale until the process
|
|
46
|
+
* restarts. Twelve templates of a few kilobytes each, read once per generation,
|
|
47
|
+
* is not a cost worth that.
|
|
48
|
+
*/
|
|
49
|
+
export function loadTemplate(language, kind, templates = knowledgePath('templates')) {
|
|
50
|
+
const files = toCorpusSource(templates);
|
|
51
|
+
const entry = `${kind}.tmpl`;
|
|
52
|
+
try {
|
|
53
|
+
return files.readText(language, entry);
|
|
54
|
+
}
|
|
55
|
+
catch (cause) {
|
|
56
|
+
throw new JazzCashConfigError(`No ${language} template for "${kind}". Expected it at ${files.locate(language, entry)}.`, { cause });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/codegen/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAqB,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;;;;GAOG;AAEH,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAE,MAAsB;IAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACpE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,mBAAmB,CAC3B,qCAAqC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,8DAA8D,CAClI,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACjG,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,IAAkB,EAClB,YAAmC,aAAa,CAAC,WAAW,CAAC;IAE7D,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,GAAG,IAAI,OAAO,CAAC;IAE7B,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,mBAAmB,CAC3B,MAAM,QAAQ,kBAAkB,IAAI,qBAAqB,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,EACzF,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { IntegrationFlow } from '../catalogue/types.js';
|
|
2
|
+
import type { JazzCashEnvironment } from '../config/environment.js';
|
|
3
|
+
/** Languages the generator emits. */
|
|
4
|
+
export declare const LANGUAGES: readonly ["php", "node", "python"];
|
|
5
|
+
export type Language = (typeof LANGUAGES)[number];
|
|
6
|
+
/** What kind of artefact to generate. */
|
|
7
|
+
export declare const TEMPLATE_KINDS: readonly ["checkout-redirect", "rest-client", "ipn-handler", "wallet-linking"];
|
|
8
|
+
export type TemplateKind = (typeof TEMPLATE_KINDS)[number];
|
|
9
|
+
export interface GeneratedFile {
|
|
10
|
+
/** Suggested path relative to the merchant's project root. */
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly language: Language;
|
|
13
|
+
readonly contents: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CodegenResult {
|
|
16
|
+
readonly flowId: string;
|
|
17
|
+
readonly language: Language;
|
|
18
|
+
readonly kind: TemplateKind;
|
|
19
|
+
readonly files: readonly GeneratedFile[];
|
|
20
|
+
/** What the merchant must still do: register URLs, set variables, run tests. */
|
|
21
|
+
readonly followUp: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* `.env` fragment for the MERCHANT'S OWN application.
|
|
24
|
+
*
|
|
25
|
+
* The generated code reads these at runtime. This is unrelated to how the MCP
|
|
26
|
+
* server itself is configured — the server never reads a `.env`.
|
|
27
|
+
*/
|
|
28
|
+
readonly envExample: string;
|
|
29
|
+
}
|
|
30
|
+
/** Values a language adapter substitutes into a template. */
|
|
31
|
+
export type TemplateValues = Readonly<Record<string, string>>;
|
|
32
|
+
export interface LanguageAdapter {
|
|
33
|
+
readonly id: Language;
|
|
34
|
+
readonly label: string;
|
|
35
|
+
/** Render a parameter map as a literal in this language. */
|
|
36
|
+
literal(parameters: ReadonlyMap<string, string>, indent: string): string;
|
|
37
|
+
/** Escape a value for a single-quoted string in this language. */
|
|
38
|
+
escape(value: string): string;
|
|
39
|
+
/** Suggested file name for one artefact kind. */
|
|
40
|
+
fileName(kind: TemplateKind, flow: IntegrationFlow): string;
|
|
41
|
+
}
|
|
42
|
+
export interface CodegenRequest {
|
|
43
|
+
readonly flow: IntegrationFlow;
|
|
44
|
+
readonly language: Language;
|
|
45
|
+
readonly kind: TemplateKind;
|
|
46
|
+
readonly environment: JazzCashEnvironment;
|
|
47
|
+
/** Optional web framework hint, used for the IPN handler. */
|
|
48
|
+
readonly framework?: string | undefined;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/codegen/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,qCAAqC;AACrC,eAAO,MAAM,SAAS,oCAAqC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,yCAAyC;AACzC,eAAO,MAAM,cAAc,gFAAiF,CAAC;AAE7G,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,6DAA6D;AAC7D,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACzE,kEAAkE;IAClE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC;CAC7D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Languages the generator emits. */
|
|
2
|
+
export const LANGUAGES = ['php', 'node', 'python'];
|
|
3
|
+
/** What kind of artefact to generate. */
|
|
4
|
+
export const TEMPLATE_KINDS = ['checkout-redirect', 'rest-client', 'ipn-handler', 'wallet-linking'];
|
|
5
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/codegen/types.ts"],"names":[],"mappings":"AAGA,qCAAqC;AACrC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAI5D,yCAAyC;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,CAAU,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type EnvironmentConfig, type JazzCashEnvironment } from './environment.js';
|
|
3
|
+
declare const profileSchema: z.ZodObject<{
|
|
4
|
+
merchantId: z.ZodString;
|
|
5
|
+
password: z.ZodString;
|
|
6
|
+
integritySalt: z.ZodString;
|
|
7
|
+
merchantMpin: z.ZodOptional<z.ZodString>;
|
|
8
|
+
returnUrl: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodURL>>;
|
|
9
|
+
ipnUrl: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodURL>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type CredentialProfileData = z.infer<typeof profileSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* A resolved merchant credential set.
|
|
14
|
+
*
|
|
15
|
+
* `toJSON` and `toString` are overridden so that an accidental interpolation or
|
|
16
|
+
* `JSON.stringify` in a log line, an error message, or a tool result cannot leak
|
|
17
|
+
* the password, salt or MPIN.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Map a payload parameter to the profile field that supplies it.
|
|
21
|
+
*
|
|
22
|
+
* Returns `undefined` for every other name, and for a credential the profile
|
|
23
|
+
* does not carry. Both the builder, which fills a payload from scratch, and the
|
|
24
|
+
* send path, which refills one whose credentials were masked for the transcript,
|
|
25
|
+
* resolve credentials through here so the two cannot drift apart — a payload
|
|
26
|
+
* signed with one profile's salt while carrying another's merchant ID is exactly
|
|
27
|
+
* the failure this single source of truth prevents.
|
|
28
|
+
*/
|
|
29
|
+
export declare function credentialParameterValue(name: string, profile: CredentialProfile): string | undefined;
|
|
30
|
+
export declare class CredentialProfile {
|
|
31
|
+
readonly environment: JazzCashEnvironment;
|
|
32
|
+
readonly merchantId: string;
|
|
33
|
+
readonly password: string;
|
|
34
|
+
readonly integritySalt: string;
|
|
35
|
+
readonly merchantMpin: string | undefined;
|
|
36
|
+
readonly returnUrl: string | undefined;
|
|
37
|
+
readonly ipnUrl: string | undefined;
|
|
38
|
+
constructor(environment: JazzCashEnvironment, data: CredentialProfileData);
|
|
39
|
+
/** Every literal that must be scrubbed from free text before it is returned. */
|
|
40
|
+
secrets(): readonly string[];
|
|
41
|
+
/** True when this profile can be used for refunds, which require the MPIN. */
|
|
42
|
+
supportsRefunds(): boolean;
|
|
43
|
+
/** Non-sensitive description, safe to show a merchant to confirm which profile is active. */
|
|
44
|
+
describe(): Record<string, string>;
|
|
45
|
+
toJSON(): Record<string, string>;
|
|
46
|
+
toString(): string;
|
|
47
|
+
}
|
|
48
|
+
export interface CredentialStore {
|
|
49
|
+
/** Resolve a profile, or throw a {@link JazzCashConfigError} naming what is missing. */
|
|
50
|
+
get(environment: JazzCashEnvironment): CredentialProfile;
|
|
51
|
+
has(environment: JazzCashEnvironment): boolean;
|
|
52
|
+
/** All secret literals across all configured profiles, for text redaction. */
|
|
53
|
+
allSecrets(): readonly string[];
|
|
54
|
+
configuredEnvironments(): readonly JazzCashEnvironment[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build the credential store.
|
|
58
|
+
*
|
|
59
|
+
* Environment variables take precedence over the credentials file for individual
|
|
60
|
+
* fields, so a shared file can be overridden per process without editing it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function loadCredentialStore(config: EnvironmentConfig, source?: NodeJS.ProcessEnv): CredentialStore;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAyB,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAyB3G,QAAA,MAAM,aAAa;;;;;;;iBAOjB,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAOlE;;;;;;GAMG;AACH;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAarG;AAED,qBAAa,iBAAiB;IAC5B,SAAgB,WAAW,EAAE,mBAAmB,CAAC;IAEjD,SAAgB,UAAU,EAAE,MAAM,CAAC;IAEnC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IAEjC,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,SAAgB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjD,SAAgB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C,SAAgB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,WAAW,EAAE,mBAAmB,EAAE,IAAI,EAAE,qBAAqB;IAUhF,gFAAgF;IACzE,OAAO,IAAI,SAAS,MAAM,EAAE;IAInC,8EAA8E;IACvE,eAAe,IAAI,OAAO;IAIjC,6FAA6F;IACtF,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAYlC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIhC,QAAQ,IAAI,MAAM;CAG1B;AAED,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,GAAG,CAAC,WAAW,EAAE,mBAAmB,GAAG,iBAAiB,CAAC;IACzD,GAAG,CAAC,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC;IAC/C,8EAA8E;IAC9E,UAAU,IAAI,SAAS,MAAM,EAAE,CAAC;IAChC,sBAAsB,IAAI,SAAS,mBAAmB,EAAE,CAAC;CAC1D;AAuED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,EACzB,MAAM,GAAE,MAAM,CAAC,UAAwB,GACtC,eAAe,CAgDjB"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { JazzCashConfigError } from '../errors.js';
|
|
4
|
+
import { maskTail, REDACTED } from '../telemetry/redaction.js';
|
|
5
|
+
import { JAZZCASH_ENVIRONMENTS } from './environment.js';
|
|
6
|
+
/**
|
|
7
|
+
* Merchant credential resolution.
|
|
8
|
+
*
|
|
9
|
+
* Credentials come from the process environment or from a JSON file kept outside
|
|
10
|
+
* the repository. They are never accepted as ordinary tool arguments except for
|
|
11
|
+
* the stateless hash and validation helpers, where a merchant may legitimately
|
|
12
|
+
* want to check a salt they are holding in front of them.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* A credential literal that is used byte for byte.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately not trimmed, unlike `merchantId`: the salt is the HMAC key and
|
|
18
|
+
* the password is hashed alongside the other values, so a leading space that the
|
|
19
|
+
* portal really issued must survive intact. A value that is *only* whitespace is
|
|
20
|
+
* rejected instead of trimmed, because it can produce nothing but a hash the
|
|
21
|
+
* gateway rejects as a mismatch — the least diagnosable failure this server has.
|
|
22
|
+
*/
|
|
23
|
+
const secretSchema = z
|
|
24
|
+
.string()
|
|
25
|
+
.min(1)
|
|
26
|
+
.refine((value) => value.trim() !== '', 'must not consist only of whitespace');
|
|
27
|
+
const profileSchema = z.object({
|
|
28
|
+
merchantId: z.string().trim().min(1),
|
|
29
|
+
password: secretSchema,
|
|
30
|
+
integritySalt: secretSchema,
|
|
31
|
+
merchantMpin: secretSchema.optional(),
|
|
32
|
+
returnUrl: z.string().trim().pipe(z.url()).optional(),
|
|
33
|
+
ipnUrl: z.string().trim().pipe(z.url()).optional(),
|
|
34
|
+
});
|
|
35
|
+
const credentialsFileSchema = z.strictObject({
|
|
36
|
+
sandbox: profileSchema.optional(),
|
|
37
|
+
production: profileSchema.optional(),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* A resolved merchant credential set.
|
|
41
|
+
*
|
|
42
|
+
* `toJSON` and `toString` are overridden so that an accidental interpolation or
|
|
43
|
+
* `JSON.stringify` in a log line, an error message, or a tool result cannot leak
|
|
44
|
+
* the password, salt or MPIN.
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Map a payload parameter to the profile field that supplies it.
|
|
48
|
+
*
|
|
49
|
+
* Returns `undefined` for every other name, and for a credential the profile
|
|
50
|
+
* does not carry. Both the builder, which fills a payload from scratch, and the
|
|
51
|
+
* send path, which refills one whose credentials were masked for the transcript,
|
|
52
|
+
* resolve credentials through here so the two cannot drift apart — a payload
|
|
53
|
+
* signed with one profile's salt while carrying another's merchant ID is exactly
|
|
54
|
+
* the failure this single source of truth prevents.
|
|
55
|
+
*/
|
|
56
|
+
export function credentialParameterValue(name, profile) {
|
|
57
|
+
switch (name) {
|
|
58
|
+
case 'pp_MerchantID':
|
|
59
|
+
return profile.merchantId;
|
|
60
|
+
case 'pp_Password':
|
|
61
|
+
return profile.password;
|
|
62
|
+
case 'pp_MerchantMPIN':
|
|
63
|
+
return profile.merchantMpin;
|
|
64
|
+
case 'pp_ReturnURL':
|
|
65
|
+
return profile.returnUrl;
|
|
66
|
+
default:
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export class CredentialProfile {
|
|
71
|
+
environment;
|
|
72
|
+
merchantId;
|
|
73
|
+
password;
|
|
74
|
+
integritySalt;
|
|
75
|
+
merchantMpin;
|
|
76
|
+
returnUrl;
|
|
77
|
+
ipnUrl;
|
|
78
|
+
constructor(environment, data) {
|
|
79
|
+
this.environment = environment;
|
|
80
|
+
this.merchantId = data.merchantId;
|
|
81
|
+
this.password = data.password;
|
|
82
|
+
this.integritySalt = data.integritySalt;
|
|
83
|
+
this.merchantMpin = data.merchantMpin;
|
|
84
|
+
this.returnUrl = data.returnUrl;
|
|
85
|
+
this.ipnUrl = data.ipnUrl;
|
|
86
|
+
}
|
|
87
|
+
/** Every literal that must be scrubbed from free text before it is returned. */
|
|
88
|
+
secrets() {
|
|
89
|
+
return [this.password, this.integritySalt, ...(this.merchantMpin === undefined ? [] : [this.merchantMpin])];
|
|
90
|
+
}
|
|
91
|
+
/** True when this profile can be used for refunds, which require the MPIN. */
|
|
92
|
+
supportsRefunds() {
|
|
93
|
+
return this.merchantMpin !== undefined;
|
|
94
|
+
}
|
|
95
|
+
/** Non-sensitive description, safe to show a merchant to confirm which profile is active. */
|
|
96
|
+
describe() {
|
|
97
|
+
return {
|
|
98
|
+
environment: this.environment,
|
|
99
|
+
merchantId: this.merchantId,
|
|
100
|
+
password: maskTail(this.password),
|
|
101
|
+
integritySalt: maskTail(this.integritySalt),
|
|
102
|
+
merchantMpin: this.merchantMpin === undefined ? '(not configured)' : REDACTED,
|
|
103
|
+
returnUrl: this.returnUrl ?? '(not configured)',
|
|
104
|
+
ipnUrl: this.ipnUrl ?? '(not configured)',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
toJSON() {
|
|
108
|
+
return this.describe();
|
|
109
|
+
}
|
|
110
|
+
toString() {
|
|
111
|
+
return `CredentialProfile(${this.environment}, merchantId=${this.merchantId}, secrets=${REDACTED})`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const ENV_VARIABLE_PREFIX = {
|
|
115
|
+
sandbox: 'JAZZCASH_SANDBOX',
|
|
116
|
+
production: 'JAZZCASH_PRODUCTION',
|
|
117
|
+
};
|
|
118
|
+
const ENV_VARIABLE_SUFFIX = {
|
|
119
|
+
merchantId: 'MERCHANT_ID',
|
|
120
|
+
password: 'PASSWORD',
|
|
121
|
+
integritySalt: 'INTEGRITY_SALT',
|
|
122
|
+
merchantMpin: 'MERCHANT_MPIN',
|
|
123
|
+
returnUrl: 'RETURN_URL',
|
|
124
|
+
ipnUrl: 'IPN_URL',
|
|
125
|
+
};
|
|
126
|
+
function readProfileFromEnv(environment, source) {
|
|
127
|
+
const prefix = ENV_VARIABLE_PREFIX[environment];
|
|
128
|
+
const result = {};
|
|
129
|
+
for (const field of Object.keys(ENV_VARIABLE_SUFFIX)) {
|
|
130
|
+
const raw = source[`${prefix}_${ENV_VARIABLE_SUFFIX[field]}`];
|
|
131
|
+
if (typeof raw === 'string' && raw !== '') {
|
|
132
|
+
// Preserve the source value here. `profileSchema` owns field-specific
|
|
133
|
+
// normalisation: identifiers and URLs are trimmed, while secrets remain
|
|
134
|
+
// byte-for-byte and its refinement rejects whitespace-only literals.
|
|
135
|
+
result[field] = raw;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
function readProfilesFromFile(path) {
|
|
141
|
+
let contents;
|
|
142
|
+
try {
|
|
143
|
+
contents = readFileSync(path, 'utf8');
|
|
144
|
+
}
|
|
145
|
+
catch (cause) {
|
|
146
|
+
throw new JazzCashConfigError(`Unable to read JAZZCASH_CREDENTIALS_FILE at ${path}.`, { cause });
|
|
147
|
+
}
|
|
148
|
+
let parsedJson;
|
|
149
|
+
try {
|
|
150
|
+
parsedJson = JSON.parse(contents);
|
|
151
|
+
}
|
|
152
|
+
catch (cause) {
|
|
153
|
+
throw new JazzCashConfigError(`JAZZCASH_CREDENTIALS_FILE at ${path} is not valid JSON.`, { cause });
|
|
154
|
+
}
|
|
155
|
+
const parsed = credentialsFileSchema.safeParse(parsedJson);
|
|
156
|
+
if (!parsed.success) {
|
|
157
|
+
const issues = parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
|
|
158
|
+
throw new JazzCashConfigError(`JAZZCASH_CREDENTIALS_FILE at ${path} has an invalid shape. ${issues}`);
|
|
159
|
+
}
|
|
160
|
+
return parsed.data;
|
|
161
|
+
}
|
|
162
|
+
function describeMissingFields(environment, issuePaths) {
|
|
163
|
+
const prefix = ENV_VARIABLE_PREFIX[environment];
|
|
164
|
+
const variables = issuePaths
|
|
165
|
+
.map((path) => ENV_VARIABLE_SUFFIX[path])
|
|
166
|
+
.filter((suffix) => suffix !== undefined)
|
|
167
|
+
.map((suffix) => `${prefix}_${suffix}`);
|
|
168
|
+
return variables.length > 0 ? variables.join(', ') : 'unknown fields';
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Build the credential store.
|
|
172
|
+
*
|
|
173
|
+
* Environment variables take precedence over the credentials file for individual
|
|
174
|
+
* fields, so a shared file can be overridden per process without editing it.
|
|
175
|
+
*/
|
|
176
|
+
export function loadCredentialStore(config, source = process.env) {
|
|
177
|
+
const fromFile = config.credentialsFile === undefined ? {} : readProfilesFromFile(config.credentialsFile);
|
|
178
|
+
const profiles = new Map();
|
|
179
|
+
const incomplete = new Map();
|
|
180
|
+
for (const environment of JAZZCASH_ENVIRONMENTS) {
|
|
181
|
+
const merged = { ...fromFile[environment], ...readProfileFromEnv(environment, source) };
|
|
182
|
+
if (Object.keys(merged).length === 0) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const parsed = profileSchema.safeParse(merged);
|
|
186
|
+
if (parsed.success) {
|
|
187
|
+
profiles.set(environment, new CredentialProfile(environment, parsed.data));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
incomplete.set(environment, describeMissingFields(environment, parsed.error.issues.map((issue) => String(issue.path[0]))));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
get(environment) {
|
|
195
|
+
const profile = profiles.get(environment);
|
|
196
|
+
if (profile !== undefined) {
|
|
197
|
+
return profile;
|
|
198
|
+
}
|
|
199
|
+
const missing = incomplete.get(environment);
|
|
200
|
+
const detail = missing === undefined
|
|
201
|
+
? `Set ${ENV_VARIABLE_PREFIX[environment]}_MERCHANT_ID, _PASSWORD and _INTEGRITY_SALT, or configure JAZZCASH_CREDENTIALS_FILE.`
|
|
202
|
+
: `The following are missing or invalid: ${missing}.`;
|
|
203
|
+
throw new JazzCashConfigError(`No usable ${environment} credentials are configured. ${detail}`);
|
|
204
|
+
},
|
|
205
|
+
has(environment) {
|
|
206
|
+
return profiles.has(environment);
|
|
207
|
+
},
|
|
208
|
+
allSecrets() {
|
|
209
|
+
return [...profiles.values()].flatMap((profile) => profile.secrets());
|
|
210
|
+
},
|
|
211
|
+
configuredEnvironments() {
|
|
212
|
+
return [...profiles.keys()];
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type LogLevel } from '../telemetry/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Server-level configuration, read once at start-up from the process environment.
|
|
4
|
+
*
|
|
5
|
+
* Failures are fatal and reported with the offending variable named, because a
|
|
6
|
+
* half-configured payment tool is more dangerous than one that refuses to start.
|
|
7
|
+
*/
|
|
8
|
+
export declare const JAZZCASH_ENVIRONMENTS: readonly ["sandbox", "production"];
|
|
9
|
+
export type JazzCashEnvironment = (typeof JAZZCASH_ENVIRONMENTS)[number];
|
|
10
|
+
export interface EnvironmentConfig {
|
|
11
|
+
/** Default environment for tools that do not receive an explicit one. */
|
|
12
|
+
readonly defaultEnvironment: JazzCashEnvironment;
|
|
13
|
+
/**
|
|
14
|
+
* Master switch for production money movement. Even when true, each such tool
|
|
15
|
+
* call must additionally pass `confirmLiveEnvironment: true`.
|
|
16
|
+
*/
|
|
17
|
+
readonly allowLive: boolean;
|
|
18
|
+
readonly httpTimeoutMs: number;
|
|
19
|
+
readonly logLevel: LogLevel;
|
|
20
|
+
readonly credentialsFile: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
export declare function loadEnvironmentConfig(source?: NodeJS.ProcessEnv): EnvironmentConfig;
|
|
23
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;GAKG;AAEH,eAAO,MAAM,qBAAqB,oCAAqC,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,QAAQ,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAiCD,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CAiBhG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { JazzCashConfigError } from '../errors.js';
|
|
3
|
+
import { LOG_LEVELS } from '../telemetry/logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* Server-level configuration, read once at start-up from the process environment.
|
|
6
|
+
*
|
|
7
|
+
* Failures are fatal and reported with the offending variable named, because a
|
|
8
|
+
* half-configured payment tool is more dangerous than one that refuses to start.
|
|
9
|
+
*/
|
|
10
|
+
export const JAZZCASH_ENVIRONMENTS = ['sandbox', 'production'];
|
|
11
|
+
const booleanFromString = z
|
|
12
|
+
.string()
|
|
13
|
+
.trim()
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.refine((value) => ['true', 'false', '1', '0', 'yes', 'no'].includes(value), {
|
|
16
|
+
message: 'must be one of: true, false, 1, 0, yes, no',
|
|
17
|
+
})
|
|
18
|
+
.transform((value) => ['true', '1', 'yes'].includes(value));
|
|
19
|
+
const defaultAllowLive = false;
|
|
20
|
+
const environmentSchema = z.object({
|
|
21
|
+
JAZZCASH_ENVIRONMENT: z.enum(JAZZCASH_ENVIRONMENTS).default('sandbox'),
|
|
22
|
+
JAZZCASH_ALLOW_LIVE: booleanFromString.default(defaultAllowLive),
|
|
23
|
+
JAZZCASH_HTTP_TIMEOUT_MS: z.coerce.number().int().positive().max(600_000).default(30_000),
|
|
24
|
+
JAZZCASH_LOG_LEVEL: z.enum(LOG_LEVELS).default('info'),
|
|
25
|
+
JAZZCASH_CREDENTIALS_FILE: z.string().trim().min(1).optional(),
|
|
26
|
+
});
|
|
27
|
+
/** Treat empty-string variables as unset; harness `env` blocks routinely contain blanks. */
|
|
28
|
+
function compact(source) {
|
|
29
|
+
const result = {};
|
|
30
|
+
for (const key of Object.keys(source)) {
|
|
31
|
+
const value = source[key];
|
|
32
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
33
|
+
result[key] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
export function loadEnvironmentConfig(source = process.env) {
|
|
39
|
+
const input = compact(source);
|
|
40
|
+
const parsed = environmentSchema.safeParse(input);
|
|
41
|
+
if (!parsed.success) {
|
|
42
|
+
const issues = parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
|
|
43
|
+
throw new JazzCashConfigError(`Invalid server configuration. ${issues}`);
|
|
44
|
+
}
|
|
45
|
+
const output = parsed.data;
|
|
46
|
+
return {
|
|
47
|
+
defaultEnvironment: output.JAZZCASH_ENVIRONMENT,
|
|
48
|
+
allowLive: output.JAZZCASH_ALLOW_LIVE,
|
|
49
|
+
httpTimeoutMs: output.JAZZCASH_HTTP_TIMEOUT_MS,
|
|
50
|
+
logLevel: output.JAZZCASH_LOG_LEVEL,
|
|
51
|
+
credentialsFile: output.JAZZCASH_CREDENTIALS_FILE,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FlowCatalogue } from '../catalogue/flows.js';
|
|
2
|
+
import type { CredentialStore } from '../config/credentials.js';
|
|
3
|
+
import type { EnvironmentConfig } from '../config/environment.js';
|
|
4
|
+
import type { HttpClient } from '../gateway/http-client.js';
|
|
5
|
+
import type { Logger } from '../telemetry/logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Everything a tool may depend on without reading the documentation corpus.
|
|
8
|
+
*
|
|
9
|
+
* This is the smaller half of {@link import('../dependencies.js').ServerDependencies},
|
|
10
|
+
* and it exists as its own module for two reasons that are not stylistic:
|
|
11
|
+
*
|
|
12
|
+
* 1. **It is the credential half's whole world.** The four tools that cannot
|
|
13
|
+
* run without a merchant credential read exactly one knowledge dependency —
|
|
14
|
+
* the flow catalogue — and never touch the transcribed documents, the search
|
|
15
|
+
* index or the symptom base. Typing their registrars against this interface
|
|
16
|
+
* turns that from a fact somebody checked once into one the compiler
|
|
17
|
+
* rechecks on every build: reaching for `deps.corpus` inside a credential
|
|
18
|
+
* tool stops being a review comment and becomes an error.
|
|
19
|
+
* 2. **It bounds what has to travel.** The connector is published as a
|
|
20
|
+
* self-contained package built from the module graph reachable from here, so
|
|
21
|
+
* anything this interface names is code that ships to merchants. Splitting
|
|
22
|
+
* the file rather than merely splitting the interface is what keeps that
|
|
23
|
+
* graph honest: `../dependencies.js` type-imports the corpus, the search
|
|
24
|
+
* index and the symptom base, and a type-only import still drags its module
|
|
25
|
+
* into the graph that a build has to typecheck.
|
|
26
|
+
*/
|
|
27
|
+
export interface CoreDependencies {
|
|
28
|
+
readonly logger: Logger;
|
|
29
|
+
readonly config: EnvironmentConfig;
|
|
30
|
+
readonly credentials: CredentialStore;
|
|
31
|
+
/** Flow specifications, loaded and validated once at start-up. */
|
|
32
|
+
readonly catalogue: FlowCatalogue;
|
|
33
|
+
/**
|
|
34
|
+
* Transport for gateway calls.
|
|
35
|
+
*
|
|
36
|
+
* Optional and normally absent, in which case a client is built per call from
|
|
37
|
+
* the configured timeout. Present so that every tool which reaches the network
|
|
38
|
+
* — including orchestration tools that do not expose a transport argument of
|
|
39
|
+
* their own — can be exercised against a stub instead of the live gateway.
|
|
40
|
+
*/
|
|
41
|
+
readonly httpClient?: HttpClient | undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=dependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/core/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAC9C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/core/dependencies.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { CoreDependencies } from './dependencies.js';
|
|
3
|
+
/**
|
|
4
|
+
* Uniform registration signature, parameterised by what the registrar needs.
|
|
5
|
+
*
|
|
6
|
+
* Holding all registrations behind one shape keeps `createServer` free of
|
|
7
|
+
* per-feature knowledge, and isolates the SDK surface that changes between major
|
|
8
|
+
* versions: migrating to SDK v2 means editing these modules and nothing else.
|
|
9
|
+
*
|
|
10
|
+
* The type parameter is what lets a registrar declare the *smaller* dependency
|
|
11
|
+
* set it actually uses. Under `strictFunctionTypes`, parameter contravariance
|
|
12
|
+
* makes every `RegistrarFor<CoreDependencies>` assignable to a
|
|
13
|
+
* `RegistrarFor<ServerDependencies>`, so the full server still composes one
|
|
14
|
+
* homogeneous list while the credential tools carry a narrower, checkable claim
|
|
15
|
+
* about what they read.
|
|
16
|
+
*/
|
|
17
|
+
export type RegistrarFor<D> = (server: McpServer, deps: D) => void;
|
|
18
|
+
/**
|
|
19
|
+
* A registrar that reads no part of the documentation corpus.
|
|
20
|
+
*
|
|
21
|
+
* See {@link CoreDependencies} for why that restriction is expressed in the type
|
|
22
|
+
* system rather than in a comment.
|
|
23
|
+
*/
|
|
24
|
+
export type CoreRegistrar = RegistrarFor<CoreDependencies>;
|
|
25
|
+
/**
|
|
26
|
+
* Apply a list of registrars to a server instance.
|
|
27
|
+
*
|
|
28
|
+
* Generic in the dependency set so that a host serving only the credential tools
|
|
29
|
+
* can apply them with only {@link CoreDependencies} in hand — it holds no corpus
|
|
30
|
+
* to pass, which is the point.
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyRegistrars<D>(server: McpServer, deps: D, registrars: readonly RegistrarFor<D>[]): void;
|
|
33
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAI3G"}
|