@xapps-platform/xapp-manifest 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6862,22 +6862,134 @@ function normalizeHookIdempotencyScope(value) {
6862
6862
 
6863
6863
  // src/hookRegistry.ts
6864
6864
  var HOOK_REGISTRY = [
6865
- { trigger: "before:installation_create", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6866
- { trigger: "before:widget_load", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6867
- { trigger: "before:session_open", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6868
- { trigger: "before:thread_create", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6869
- { trigger: "before:tool_run", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: true, auditCategory: "guard_policy" },
6870
- { trigger: "after:install", implemented: true, blockingDefault: false, allowedEffectKinds: ["policy", "integration_call"], allowsDelegatedExecution: false, auditCategory: "lifecycle" },
6871
- { trigger: "after:link_complete", implemented: true, blockingDefault: false, allowedEffectKinds: ["policy", "integration_call"], allowsDelegatedExecution: false, auditCategory: "lifecycle" },
6872
- { trigger: "before:link_revoke", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6873
- { trigger: "before:uninstall", implemented: true, blockingDefault: true, allowedEffectKinds: ["policy"], allowsDelegatedExecution: false, auditCategory: "guard_policy" },
6874
- { trigger: "after:tool_complete", implemented: true, blockingDefault: false, allowedEffectKinds: ["policy", "integration_call"], allowsDelegatedExecution: true, auditCategory: "response" },
6875
- { trigger: "after:uninstall", implemented: true, blockingDefault: false, allowedEffectKinds: ["policy", "integration_call"], allowsDelegatedExecution: false, auditCategory: "lifecycle" },
6876
- { trigger: "after:payment_completed", implemented: true, blockingDefault: false, allowedEffectKinds: ["invoice", "policy", "notification", "integration_call"], allowsDelegatedExecution: true, auditCategory: "payment" },
6877
- { trigger: "after:payment_failed", implemented: false, blockingDefault: false, allowedEffectKinds: ["notification", "integration_call"], allowsDelegatedExecution: true, auditCategory: "payment" },
6878
- { trigger: "after:request_created", implemented: true, blockingDefault: false, allowedEffectKinds: ["notification", "integration_call"], allowsDelegatedExecution: true, auditCategory: "request" },
6879
- { trigger: "after:response_ready", implemented: false, blockingDefault: false, allowedEffectKinds: ["notification", "integration_call"], allowsDelegatedExecution: true, auditCategory: "response" },
6880
- { trigger: "after:response_finalized", implemented: true, blockingDefault: false, allowedEffectKinds: ["invoice", "policy", "notification", "integration_call"], allowsDelegatedExecution: true, auditCategory: "response" }
6865
+ {
6866
+ trigger: "before:installation_create",
6867
+ implemented: true,
6868
+ blockingDefault: true,
6869
+ allowedEffectKinds: ["policy"],
6870
+ allowsDelegatedExecution: false,
6871
+ auditCategory: "guard_policy"
6872
+ },
6873
+ {
6874
+ trigger: "before:widget_load",
6875
+ implemented: true,
6876
+ blockingDefault: true,
6877
+ allowedEffectKinds: ["policy"],
6878
+ allowsDelegatedExecution: false,
6879
+ auditCategory: "guard_policy"
6880
+ },
6881
+ {
6882
+ trigger: "before:session_open",
6883
+ implemented: true,
6884
+ blockingDefault: true,
6885
+ allowedEffectKinds: ["policy"],
6886
+ allowsDelegatedExecution: false,
6887
+ auditCategory: "guard_policy"
6888
+ },
6889
+ {
6890
+ trigger: "before:thread_create",
6891
+ implemented: true,
6892
+ blockingDefault: true,
6893
+ allowedEffectKinds: ["policy"],
6894
+ allowsDelegatedExecution: false,
6895
+ auditCategory: "guard_policy"
6896
+ },
6897
+ {
6898
+ trigger: "before:tool_run",
6899
+ implemented: true,
6900
+ blockingDefault: true,
6901
+ allowedEffectKinds: ["policy"],
6902
+ allowsDelegatedExecution: true,
6903
+ auditCategory: "guard_policy"
6904
+ },
6905
+ {
6906
+ trigger: "after:install",
6907
+ implemented: true,
6908
+ blockingDefault: false,
6909
+ allowedEffectKinds: ["policy", "integration_call"],
6910
+ allowsDelegatedExecution: false,
6911
+ auditCategory: "lifecycle"
6912
+ },
6913
+ {
6914
+ trigger: "after:link_complete",
6915
+ implemented: true,
6916
+ blockingDefault: false,
6917
+ allowedEffectKinds: ["policy", "integration_call"],
6918
+ allowsDelegatedExecution: false,
6919
+ auditCategory: "lifecycle"
6920
+ },
6921
+ {
6922
+ trigger: "before:link_revoke",
6923
+ implemented: true,
6924
+ blockingDefault: true,
6925
+ allowedEffectKinds: ["policy"],
6926
+ allowsDelegatedExecution: false,
6927
+ auditCategory: "guard_policy"
6928
+ },
6929
+ {
6930
+ trigger: "before:uninstall",
6931
+ implemented: true,
6932
+ blockingDefault: true,
6933
+ allowedEffectKinds: ["policy"],
6934
+ allowsDelegatedExecution: false,
6935
+ auditCategory: "guard_policy"
6936
+ },
6937
+ {
6938
+ trigger: "after:tool_complete",
6939
+ implemented: true,
6940
+ blockingDefault: false,
6941
+ allowedEffectKinds: ["policy", "integration_call"],
6942
+ allowsDelegatedExecution: true,
6943
+ auditCategory: "response"
6944
+ },
6945
+ {
6946
+ trigger: "after:uninstall",
6947
+ implemented: true,
6948
+ blockingDefault: false,
6949
+ allowedEffectKinds: ["policy", "integration_call"],
6950
+ allowsDelegatedExecution: false,
6951
+ auditCategory: "lifecycle"
6952
+ },
6953
+ {
6954
+ trigger: "after:payment_completed",
6955
+ implemented: true,
6956
+ blockingDefault: false,
6957
+ allowedEffectKinds: ["invoice", "policy", "notification", "integration_call"],
6958
+ allowsDelegatedExecution: true,
6959
+ auditCategory: "payment"
6960
+ },
6961
+ {
6962
+ trigger: "after:payment_failed",
6963
+ implemented: false,
6964
+ blockingDefault: false,
6965
+ allowedEffectKinds: ["notification", "integration_call"],
6966
+ allowsDelegatedExecution: true,
6967
+ auditCategory: "payment"
6968
+ },
6969
+ {
6970
+ trigger: "after:request_created",
6971
+ implemented: true,
6972
+ blockingDefault: false,
6973
+ allowedEffectKinds: ["notification", "integration_call"],
6974
+ allowsDelegatedExecution: true,
6975
+ auditCategory: "request"
6976
+ },
6977
+ {
6978
+ trigger: "after:response_ready",
6979
+ implemented: false,
6980
+ blockingDefault: false,
6981
+ allowedEffectKinds: ["notification", "integration_call"],
6982
+ allowsDelegatedExecution: true,
6983
+ auditCategory: "response"
6984
+ },
6985
+ {
6986
+ trigger: "after:response_finalized",
6987
+ implemented: true,
6988
+ blockingDefault: false,
6989
+ allowedEffectKinds: ["invoice", "policy", "notification", "integration_call"],
6990
+ allowsDelegatedExecution: true,
6991
+ auditCategory: "response"
6992
+ }
6881
6993
  ];
6882
6994
  var HOOK_REGISTRY_MAP = new Map(HOOK_REGISTRY.map((entry) => [entry.trigger, entry]));
6883
6995
  function getHookRegistryEntry(trigger) {
@@ -6954,6 +7066,51 @@ function buildNotificationTemplateRegistry(templates) {
6954
7066
  }
6955
7067
  return registry;
6956
7068
  }
7069
+ function normalizeTemplateLocale(input, fallbackLocale = "en") {
7070
+ const raw = String(input || "").trim();
7071
+ if (!raw) return fallbackLocale;
7072
+ const parts = raw.replace(/_/g, "-").split("-").map((part) => part.trim()).filter(Boolean);
7073
+ if (!parts.length) return fallbackLocale;
7074
+ const [language, ...rest] = parts;
7075
+ return [language.toLowerCase(), ...rest.map((part) => part.toUpperCase())].join("-");
7076
+ }
7077
+ function getTemplateLocaleCandidates(input, fallbackLocale = "en") {
7078
+ const normalizedFallback = normalizeTemplateLocale(fallbackLocale, "en");
7079
+ const normalized = normalizeTemplateLocale(input, normalizedFallback);
7080
+ const out = /* @__PURE__ */ new Set([normalized]);
7081
+ const dash = normalized.indexOf("-");
7082
+ if (dash > 0) out.add(normalized.slice(0, dash));
7083
+ const fallbackDash = normalizedFallback.indexOf("-");
7084
+ if (fallbackDash > 0) out.add(normalizedFallback.slice(0, fallbackDash));
7085
+ out.add(normalizedFallback);
7086
+ out.add("en");
7087
+ return Array.from(out);
7088
+ }
7089
+ function resolveNotificationTemplateVariant(input) {
7090
+ const templateRef = String(input.templateRef || "").trim();
7091
+ if (!templateRef) return null;
7092
+ const registry = buildNotificationTemplateRegistry(input.templates);
7093
+ const exact = registry.get(templateRef);
7094
+ const templates = Array.isArray(input.templates) ? input.templates.filter(
7095
+ (template) => Boolean(template && typeof template === "object")
7096
+ ) : [];
7097
+ const familyMatches = templates.filter(
7098
+ (template) => String(template.family || "").trim() === templateRef
7099
+ );
7100
+ if (familyMatches.length > 0) {
7101
+ const candidates = getTemplateLocaleCandidates(input.locale, input.fallbackLocale);
7102
+ for (const candidate of candidates) {
7103
+ const match = familyMatches.find(
7104
+ (template) => normalizeTemplateLocale(template.locale, "") === candidate
7105
+ );
7106
+ if (match) return match;
7107
+ }
7108
+ const noLocaleMatch = familyMatches.find((template) => !String(template.locale || "").trim());
7109
+ if (noLocaleMatch) return noLocaleMatch;
7110
+ }
7111
+ if (exact) return exact;
7112
+ return familyMatches[0] || null;
7113
+ }
6957
7114
  function readNotificationRef(config) {
6958
7115
  if (!config || typeof config !== "object" || Array.isArray(config)) return "";
6959
7116
  return String(config.notification_ref ?? config.notificationRef ?? "").trim();
@@ -6976,7 +7133,10 @@ function resolveNotificationTemplateConfig(input) {
6976
7133
  }
6977
7134
  };
6978
7135
  }
6979
- const template = input.templates.get(templateRef);
7136
+ const template = resolveNotificationTemplateVariant({
7137
+ templates: Array.from(input.templates.values()),
7138
+ templateRef
7139
+ });
6980
7140
  if (!template) {
6981
7141
  return {
6982
7142
  ok: false,
@@ -7076,6 +7236,51 @@ function buildInvoiceTemplateRegistry(templates) {
7076
7236
  }
7077
7237
  return registry;
7078
7238
  }
7239
+ function normalizeTemplateLocale2(input, fallbackLocale = "en") {
7240
+ const raw = String(input || "").trim();
7241
+ if (!raw) return fallbackLocale;
7242
+ const parts = raw.replace(/_/g, "-").split("-").map((part) => part.trim()).filter(Boolean);
7243
+ if (!parts.length) return fallbackLocale;
7244
+ const [language, ...rest] = parts;
7245
+ return [language.toLowerCase(), ...rest.map((part) => part.toUpperCase())].join("-");
7246
+ }
7247
+ function getTemplateLocaleCandidates2(input, fallbackLocale = "en") {
7248
+ const normalizedFallback = normalizeTemplateLocale2(fallbackLocale, "en");
7249
+ const normalized = normalizeTemplateLocale2(input, normalizedFallback);
7250
+ const out = /* @__PURE__ */ new Set([normalized]);
7251
+ const dash = normalized.indexOf("-");
7252
+ if (dash > 0) out.add(normalized.slice(0, dash));
7253
+ const fallbackDash = normalizedFallback.indexOf("-");
7254
+ if (fallbackDash > 0) out.add(normalizedFallback.slice(0, fallbackDash));
7255
+ out.add(normalizedFallback);
7256
+ out.add("en");
7257
+ return Array.from(out);
7258
+ }
7259
+ function resolveInvoiceTemplateVariant(input) {
7260
+ const templateRef = String(input.templateRef || "").trim();
7261
+ if (!templateRef) return null;
7262
+ const registry = buildInvoiceTemplateRegistry(input.templates);
7263
+ const exact = registry.get(templateRef);
7264
+ const templates = Array.isArray(input.templates) ? input.templates.filter(
7265
+ (template) => Boolean(template && typeof template === "object")
7266
+ ) : [];
7267
+ const familyMatches = templates.filter(
7268
+ (template) => String(template.family || "").trim() === templateRef
7269
+ );
7270
+ if (familyMatches.length > 0) {
7271
+ const candidates = getTemplateLocaleCandidates2(input.locale, input.fallbackLocale);
7272
+ for (const candidate of candidates) {
7273
+ const match = familyMatches.find(
7274
+ (template) => normalizeTemplateLocale2(template.locale, "") === candidate
7275
+ );
7276
+ if (match) return match;
7277
+ }
7278
+ const noLocaleMatch = familyMatches.find((template) => !String(template.locale || "").trim());
7279
+ if (noLocaleMatch) return noLocaleMatch;
7280
+ }
7281
+ if (exact) return exact;
7282
+ return familyMatches[0] || null;
7283
+ }
7079
7284
  function readInvoiceRef(config) {
7080
7285
  if (!config || typeof config !== "object" || Array.isArray(config)) return "";
7081
7286
  return String(config.invoice_ref ?? config.invoiceRef ?? "").trim();
@@ -7100,7 +7305,10 @@ function resolveInvoiceTemplateConfig(input) {
7100
7305
  }
7101
7306
  };
7102
7307
  }
7103
- const template = input.templates.get(templateRef);
7308
+ const template = resolveInvoiceTemplateVariant({
7309
+ templates: Array.from(input.templates.values()),
7310
+ templateRef
7311
+ });
7104
7312
  if (!template) {
7105
7313
  return {
7106
7314
  ok: false,
@@ -7313,10 +7521,14 @@ function normalizeRequiredSubjectProfileFamily(value) {
7313
7521
  if (["identity_basic", "identity-basic", "identity", "basic_identity"].includes(normalized)) {
7314
7522
  return "identity_basic";
7315
7523
  }
7316
- if (["billing_individual", "billing-individual", "individual", "person", "natural_person"].includes(normalized)) {
7524
+ if (["billing_individual", "billing-individual", "individual", "person", "natural_person"].includes(
7525
+ normalized
7526
+ )) {
7317
7527
  return "billing_individual";
7318
7528
  }
7319
- if (["billing_business", "billing-business", "business", "company", "organization"].includes(normalized)) {
7529
+ if (["billing_business", "billing-business", "business", "company", "organization"].includes(
7530
+ normalized
7531
+ )) {
7320
7532
  return "billing_business";
7321
7533
  }
7322
7534
  return null;
@@ -7378,23 +7590,76 @@ function resolveSubjectProfileRequirement(config) {
7378
7590
  }
7379
7591
 
7380
7592
  // src/index.ts
7593
+ function isLocalizedTextRecord(value) {
7594
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
7595
+ return Object.values(value).every((entry) => entry == null || typeof entry === "string");
7596
+ }
7597
+ function normalizeManifestLocale(input, fallbackLocale = "en") {
7598
+ const raw = String(input || "").trim();
7599
+ if (!raw) return fallbackLocale;
7600
+ const parts = raw.split("-").map((part) => part.trim()).filter(Boolean);
7601
+ if (!parts.length) return fallbackLocale;
7602
+ const [language, ...rest] = parts;
7603
+ return [language.toLowerCase(), ...rest.map((part) => part.toUpperCase())].join("-");
7604
+ }
7605
+ function getManifestLocaleCandidates(input, fallbackLocale = "en") {
7606
+ const normalizedFallback = normalizeManifestLocale(fallbackLocale, "en");
7607
+ const normalized = normalizeManifestLocale(input, normalizedFallback);
7608
+ const out = /* @__PURE__ */ new Set([normalized]);
7609
+ const dash = normalized.indexOf("-");
7610
+ if (dash > 0) out.add(normalized.slice(0, dash));
7611
+ const fallbackDash = normalizedFallback.indexOf("-");
7612
+ if (fallbackDash > 0) out.add(normalizedFallback.slice(0, fallbackDash));
7613
+ out.add(normalizedFallback);
7614
+ out.add("en");
7615
+ return Array.from(out);
7616
+ }
7617
+ function resolveManifestLocalizedText(value, locale, fallbackLocale = "en") {
7618
+ if (typeof value === "string") return value;
7619
+ if (!isLocalizedTextRecord(value)) return "";
7620
+ for (const candidate of getManifestLocaleCandidates(locale, fallbackLocale)) {
7621
+ const resolved = value[candidate];
7622
+ if (typeof resolved === "string" && resolved.trim()) return resolved;
7623
+ }
7624
+ for (const resolved of Object.values(value)) {
7625
+ if (typeof resolved === "string" && resolved.trim()) return resolved;
7626
+ }
7627
+ return "";
7628
+ }
7629
+ function localizedTextSchema(maxLength, minLength = 0) {
7630
+ const stringRule = { type: "string", maxLength };
7631
+ if (minLength > 0) stringRule.minLength = minLength;
7632
+ return {
7633
+ anyOf: [
7634
+ stringRule,
7635
+ {
7636
+ type: "object",
7637
+ minProperties: 1,
7638
+ propertyNames: { type: "string", minLength: 2, maxLength: 32 },
7639
+ additionalProperties: {
7640
+ anyOf: [{ ...stringRule }, { type: "null" }]
7641
+ }
7642
+ }
7643
+ ]
7644
+ };
7645
+ }
7381
7646
  var xappManifestJsonSchema = {
7382
7647
  type: "object",
7383
7648
  required: ["name", "slug", "version", "tools", "widgets"],
7384
7649
  additionalProperties: false,
7385
7650
  properties: {
7386
- title: { type: "string", maxLength: 200 },
7651
+ title: localizedTextSchema(200),
7387
7652
  name: { type: "string", minLength: 1, maxLength: 200 },
7388
7653
  slug: { type: "string", minLength: 1, maxLength: 100 },
7389
- description: { type: "string", maxLength: 2e3 },
7654
+ description: localizedTextSchema(2e3),
7390
7655
  image: { type: "string", maxLength: 2048 },
7391
7656
  tags: { type: "array", maxItems: 50, items: { type: "string", maxLength: 64 } },
7392
7657
  terms: {
7393
7658
  type: "object",
7394
7659
  additionalProperties: false,
7395
7660
  properties: {
7396
- title: { type: "string", maxLength: 200 },
7397
- text: { type: "string", maxLength: 2e4 },
7661
+ title: localizedTextSchema(200),
7662
+ text: localizedTextSchema(2e4),
7398
7663
  url: { type: "string", maxLength: 2048 },
7399
7664
  version: { type: "string", maxLength: 64 }
7400
7665
  }
@@ -7655,8 +7920,8 @@ var xappManifestJsonSchema = {
7655
7920
  additionalProperties: false,
7656
7921
  properties: {
7657
7922
  tool_name: { type: "string", minLength: 1, maxLength: 100 },
7658
- title: { type: "string", minLength: 1, maxLength: 200 },
7659
- description: { type: "string", maxLength: 2e3 },
7923
+ title: localizedTextSchema(200, 1),
7924
+ description: localizedTextSchema(2e3),
7660
7925
  input_schema: { type: "object" },
7661
7926
  input_ui_schema: { type: "object" },
7662
7927
  output_ui_schema: { type: "object" },
@@ -7713,12 +7978,12 @@ var xappManifestJsonSchema = {
7713
7978
  enum: ["platform", "publisher", "json-forms", "ui-kit", "app-shell"]
7714
7979
  },
7715
7980
  bind_tool_name: { type: "string", maxLength: 100 },
7716
- title: { type: "string", minLength: 1, maxLength: 200 },
7981
+ title: localizedTextSchema(200, 1),
7717
7982
  accessibility: {
7718
7983
  type: "object",
7719
7984
  additionalProperties: false,
7720
7985
  properties: {
7721
- label: { type: "string", minLength: 1, maxLength: 300 },
7986
+ label: localizedTextSchema(300, 1),
7722
7987
  role: { type: "string", minLength: 1, maxLength: 50 }
7723
7988
  }
7724
7989
  },
@@ -7811,19 +8076,237 @@ var xappManifestJsonSchema = {
7811
8076
  type: "object",
7812
8077
  additionalProperties: false,
7813
8078
  properties: {
7814
- executor_mode: { type: "string", enum: ["PUBLIC_EXECUTOR", "PRIVATE_EXECUTOR", "AGENT_TUNNEL"] },
8079
+ executor_mode: {
8080
+ type: "string",
8081
+ enum: ["PUBLIC_EXECUTOR", "PRIVATE_EXECUTOR", "AGENT_TUNNEL"]
8082
+ },
7815
8083
  auth_mode: { type: "string", enum: ["PUBLISHER_APP", "USER_DELEGATED", "HYBRID"] },
7816
8084
  signing_policy: { type: "string", enum: ["none", "subject_proof", "publisher_proof"] },
7817
8085
  webhooks: { type: "object" },
7818
8086
  proxy_policy: { type: "object" }
7819
8087
  }
7820
8088
  },
7821
- payment_guard_definitions: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: false, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, payment_type: { type: "string", maxLength: 100 }, payment_issuer_mode: { type: "string", maxLength: 100, enum: ["owner_managed", "gateway_managed", "tenant_delegated", "publisher_delegated", "any"] }, payment_scheme: { type: "string", maxLength: 100 }, payment_network: { type: "string", maxLength: 100 }, payment_allowed_issuers: { type: "array", maxItems: 20, items: { type: "string", maxLength: 100, enum: ["tenant", "publisher", "gateway", "tenant_delegated", "publisher_delegated"] } }, payment_return_contract: { type: "string", maxLength: 200 }, payment_return_required: { type: "boolean" }, payment_return_max_age_s: { type: "number", minimum: 0, maximum: 86400 }, payment_return_hmac_secret_refs: { type: "object" }, payment_return_hmac_secrets: { type: "object" }, payment_return_hmac_delegated_secret_refs: { type: "object" }, payment_return_hmac_delegated_secrets: { type: "object" }, payment_provider_credentials: { type: "object" }, payment_provider_credentials_refs: { type: "object" }, payment_provider_secret_refs: { type: "object" }, pricing_model: { type: "string", maxLength: 100 }, pricing: { type: "object", additionalProperties: false, properties: { currency: { type: "string", maxLength: 32 }, default_amount: { type: "number" }, xapp_prices: { type: "object", additionalProperties: { type: "number" } }, tool_overrides: { type: "object", additionalProperties: { type: "number" } }, description: { type: "string", maxLength: 500 }, asset: { type: "string", maxLength: 256 }, pay_to: { type: "string", maxLength: 256 }, payTo: { type: "string", maxLength: 256 } } }, receipt_field: { type: "string", maxLength: 200 }, payment_url: { type: "string", maxLength: 2048 }, accepts: { type: "array", maxItems: 20, items: { type: "object", additionalProperties: true } }, payment_ui: { type: "object" }, policy: { type: "object" }, action: { type: "object" }, owner_override_allowlist: { type: "array", maxItems: 100, items: { type: "string", minLength: 1, maxLength: 200 } }, owner_pricing_floor: { type: "object", additionalProperties: false, properties: { default_amount: { type: "number" }, xapp_prices: { type: "object", additionalProperties: { type: "number" } }, tool_overrides: { type: "object", additionalProperties: { type: "number" } } } } } } },
7822
- subject_profile_guard_definitions: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: false, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, policy: { type: "object" }, action: { type: "object" }, tools: { type: "array", maxItems: 100, items: { type: "string", minLength: 1, maxLength: 200 } }, subject_profile_requirement: { type: "object" }, subject_profile_remediation: { type: "object" }, subject_profile_sources: { type: "object" }, owner_override_allowlist: { type: "array", maxItems: 100, items: { type: "string", minLength: 1, maxLength: 200 } } } } },
7823
- notification_definitions: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: false, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, channel: { type: "string", enum: ["email"] }, effect_kind: { type: "string", enum: ["policy", "invoice", "notification", "integration_call"] }, effectKind: { type: "string", enum: ["policy", "invoice", "notification", "integration_call"] }, provider_key: { type: "string", maxLength: 100 }, providerKey: { type: "string", maxLength: 100 }, execution_mode: { type: "string", maxLength: 100 }, executionMode: { type: "string", maxLength: 100 }, provider_scope: { type: "string", maxLength: 100 }, providerScope: { type: "string", maxLength: 100 }, provider_execution: { type: "string", maxLength: 100 }, providerExecution: { type: "string", maxLength: 100 }, failure_policy: { type: "string", maxLength: 100 }, failurePolicy: { type: "string", maxLength: 100 }, retry_policy: { type: "object" }, retryPolicy: { type: "object" }, idempotency_scope: { type: "string", maxLength: 100 }, idempotencyScope: { type: "string", maxLength: 100 }, template_ref: { type: "string", maxLength: 200 }, templateRef: { type: "string", maxLength: 200 }, target: { type: "object" }, template: { type: "object" } } } },
7824
- notification_templates: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: false, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, channel: { type: "string", enum: ["email"] }, subject: { type: "string", maxLength: 500 }, text: { type: "string", maxLength: 2e4 }, html: { type: "string", maxLength: 1e5 } } } },
7825
- invoice_definitions: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: false, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, provider_key: { type: "string", maxLength: 100 }, providerKey: { type: "string", maxLength: 100 }, effect_kind: { type: "string", enum: ["policy", "invoice", "notification", "integration_call"] }, effectKind: { type: "string", enum: ["policy", "invoice", "notification", "integration_call"] }, execution_mode: { type: "string", maxLength: 100 }, executionMode: { type: "string", maxLength: 100 }, provider_scope: { type: "string", maxLength: 100 }, providerScope: { type: "string", maxLength: 100 }, provider_execution: { type: "string", maxLength: 100 }, providerExecution: { type: "string", maxLength: 100 }, failure_policy: { type: "string", maxLength: 100 }, failurePolicy: { type: "string", maxLength: 100 }, idempotency_scope: { type: "string", maxLength: 100 }, idempotencyScope: { type: "string", maxLength: 100 }, invoice_template_ref: { type: "string", maxLength: 200 }, invoiceTemplateRef: { type: "string", maxLength: 200 }, invoice: { type: "object" }, template: { type: "object" } } } },
7826
- invoice_templates: { type: "array", maxItems: 50, items: { type: "object", required: ["name"], additionalProperties: true, properties: { name: { type: "string", minLength: 1, maxLength: 200 }, title: { type: "string", maxLength: 500 }, text: { type: "string", maxLength: 2e4 }, html: { type: "string", maxLength: 1e5 } } } }
8089
+ payment_guard_definitions: {
8090
+ type: "array",
8091
+ maxItems: 50,
8092
+ items: {
8093
+ type: "object",
8094
+ required: ["name"],
8095
+ additionalProperties: false,
8096
+ properties: {
8097
+ name: { type: "string", minLength: 1, maxLength: 200 },
8098
+ payment_type: { type: "string", maxLength: 100 },
8099
+ payment_issuer_mode: {
8100
+ type: "string",
8101
+ maxLength: 100,
8102
+ enum: [
8103
+ "owner_managed",
8104
+ "gateway_managed",
8105
+ "tenant_delegated",
8106
+ "publisher_delegated",
8107
+ "any"
8108
+ ]
8109
+ },
8110
+ payment_scheme: { type: "string", maxLength: 100 },
8111
+ payment_network: { type: "string", maxLength: 100 },
8112
+ payment_allowed_issuers: {
8113
+ type: "array",
8114
+ maxItems: 20,
8115
+ items: {
8116
+ type: "string",
8117
+ maxLength: 100,
8118
+ enum: ["tenant", "publisher", "gateway", "tenant_delegated", "publisher_delegated"]
8119
+ }
8120
+ },
8121
+ payment_return_contract: { type: "string", maxLength: 200 },
8122
+ payment_return_required: { type: "boolean" },
8123
+ payment_return_max_age_s: { type: "number", minimum: 0, maximum: 86400 },
8124
+ payment_return_hmac_secret_refs: { type: "object" },
8125
+ payment_return_hmac_secrets: { type: "object" },
8126
+ payment_return_hmac_delegated_secret_refs: { type: "object" },
8127
+ payment_return_hmac_delegated_secrets: { type: "object" },
8128
+ payment_provider_credentials: { type: "object" },
8129
+ payment_provider_credentials_refs: { type: "object" },
8130
+ payment_provider_secret_refs: { type: "object" },
8131
+ pricing_model: { type: "string", maxLength: 100 },
8132
+ pricing: {
8133
+ type: "object",
8134
+ additionalProperties: false,
8135
+ properties: {
8136
+ currency: { type: "string", maxLength: 32 },
8137
+ default_amount: { type: "number" },
8138
+ xapp_prices: { type: "object", additionalProperties: { type: "number" } },
8139
+ tool_overrides: { type: "object", additionalProperties: { type: "number" } },
8140
+ description: { type: "string", maxLength: 500 },
8141
+ asset: { type: "string", maxLength: 256 },
8142
+ pay_to: { type: "string", maxLength: 256 },
8143
+ payTo: { type: "string", maxLength: 256 }
8144
+ }
8145
+ },
8146
+ receipt_field: { type: "string", maxLength: 200 },
8147
+ payment_url: { type: "string", maxLength: 2048 },
8148
+ accepts: {
8149
+ type: "array",
8150
+ maxItems: 20,
8151
+ items: { type: "object", additionalProperties: true }
8152
+ },
8153
+ payment_ui: { type: "object" },
8154
+ policy: { type: "object" },
8155
+ action: { type: "object" },
8156
+ owner_override_allowlist: {
8157
+ type: "array",
8158
+ maxItems: 100,
8159
+ items: { type: "string", minLength: 1, maxLength: 200 }
8160
+ },
8161
+ owner_pricing_floor: {
8162
+ type: "object",
8163
+ additionalProperties: false,
8164
+ properties: {
8165
+ default_amount: { type: "number" },
8166
+ xapp_prices: { type: "object", additionalProperties: { type: "number" } },
8167
+ tool_overrides: { type: "object", additionalProperties: { type: "number" } }
8168
+ }
8169
+ }
8170
+ }
8171
+ }
8172
+ },
8173
+ subject_profile_guard_definitions: {
8174
+ type: "array",
8175
+ maxItems: 50,
8176
+ items: {
8177
+ type: "object",
8178
+ required: ["name"],
8179
+ additionalProperties: false,
8180
+ properties: {
8181
+ name: { type: "string", minLength: 1, maxLength: 200 },
8182
+ policy: { type: "object" },
8183
+ action: { type: "object" },
8184
+ tools: {
8185
+ type: "array",
8186
+ maxItems: 100,
8187
+ items: { type: "string", minLength: 1, maxLength: 200 }
8188
+ },
8189
+ subject_profile_requirement: { type: "object" },
8190
+ subject_profile_remediation: { type: "object" },
8191
+ subject_profile_sources: { type: "object" },
8192
+ owner_override_allowlist: {
8193
+ type: "array",
8194
+ maxItems: 100,
8195
+ items: { type: "string", minLength: 1, maxLength: 200 }
8196
+ }
8197
+ }
8198
+ }
8199
+ },
8200
+ notification_definitions: {
8201
+ type: "array",
8202
+ maxItems: 50,
8203
+ items: {
8204
+ type: "object",
8205
+ required: ["name"],
8206
+ additionalProperties: false,
8207
+ properties: {
8208
+ name: { type: "string", minLength: 1, maxLength: 200 },
8209
+ channel: { type: "string", enum: ["email"] },
8210
+ effect_kind: {
8211
+ type: "string",
8212
+ enum: ["policy", "invoice", "notification", "integration_call"]
8213
+ },
8214
+ effectKind: {
8215
+ type: "string",
8216
+ enum: ["policy", "invoice", "notification", "integration_call"]
8217
+ },
8218
+ provider_key: { type: "string", maxLength: 100 },
8219
+ providerKey: { type: "string", maxLength: 100 },
8220
+ execution_mode: { type: "string", maxLength: 100 },
8221
+ executionMode: { type: "string", maxLength: 100 },
8222
+ provider_scope: { type: "string", maxLength: 100 },
8223
+ providerScope: { type: "string", maxLength: 100 },
8224
+ provider_execution: { type: "string", maxLength: 100 },
8225
+ providerExecution: { type: "string", maxLength: 100 },
8226
+ failure_policy: { type: "string", maxLength: 100 },
8227
+ failurePolicy: { type: "string", maxLength: 100 },
8228
+ retry_policy: { type: "object" },
8229
+ retryPolicy: { type: "object" },
8230
+ idempotency_scope: { type: "string", maxLength: 100 },
8231
+ idempotencyScope: { type: "string", maxLength: 100 },
8232
+ template_ref: { type: "string", maxLength: 200 },
8233
+ templateRef: { type: "string", maxLength: 200 },
8234
+ target: { type: "object" },
8235
+ template: { type: "object" }
8236
+ }
8237
+ }
8238
+ },
8239
+ notification_templates: {
8240
+ type: "array",
8241
+ maxItems: 50,
8242
+ items: {
8243
+ type: "object",
8244
+ required: ["name"],
8245
+ additionalProperties: false,
8246
+ properties: {
8247
+ name: { type: "string", minLength: 1, maxLength: 200 },
8248
+ family: { type: "string", minLength: 1, maxLength: 200 },
8249
+ locale: { type: "string", minLength: 2, maxLength: 32 },
8250
+ channel: { type: "string", enum: ["email"] },
8251
+ subject: { type: "string", maxLength: 500 },
8252
+ text: { type: "string", maxLength: 2e4 },
8253
+ html: { type: "string", maxLength: 1e5 }
8254
+ }
8255
+ }
8256
+ },
8257
+ invoice_definitions: {
8258
+ type: "array",
8259
+ maxItems: 50,
8260
+ items: {
8261
+ type: "object",
8262
+ required: ["name"],
8263
+ additionalProperties: false,
8264
+ properties: {
8265
+ name: { type: "string", minLength: 1, maxLength: 200 },
8266
+ provider_key: { type: "string", maxLength: 100 },
8267
+ providerKey: { type: "string", maxLength: 100 },
8268
+ effect_kind: {
8269
+ type: "string",
8270
+ enum: ["policy", "invoice", "notification", "integration_call"]
8271
+ },
8272
+ effectKind: {
8273
+ type: "string",
8274
+ enum: ["policy", "invoice", "notification", "integration_call"]
8275
+ },
8276
+ execution_mode: { type: "string", maxLength: 100 },
8277
+ executionMode: { type: "string", maxLength: 100 },
8278
+ provider_scope: { type: "string", maxLength: 100 },
8279
+ providerScope: { type: "string", maxLength: 100 },
8280
+ provider_execution: { type: "string", maxLength: 100 },
8281
+ providerExecution: { type: "string", maxLength: 100 },
8282
+ failure_policy: { type: "string", maxLength: 100 },
8283
+ failurePolicy: { type: "string", maxLength: 100 },
8284
+ idempotency_scope: { type: "string", maxLength: 100 },
8285
+ idempotencyScope: { type: "string", maxLength: 100 },
8286
+ invoice_template_ref: { type: "string", maxLength: 200 },
8287
+ invoiceTemplateRef: { type: "string", maxLength: 200 },
8288
+ invoice: { type: "object" },
8289
+ template: { type: "object" }
8290
+ }
8291
+ }
8292
+ },
8293
+ invoice_templates: {
8294
+ type: "array",
8295
+ maxItems: 50,
8296
+ items: {
8297
+ type: "object",
8298
+ required: ["name"],
8299
+ additionalProperties: true,
8300
+ properties: {
8301
+ name: { type: "string", minLength: 1, maxLength: 200 },
8302
+ family: { type: "string", minLength: 1, maxLength: 200 },
8303
+ locale: { type: "string", minLength: 2, maxLength: 32 },
8304
+ title: { type: "string", maxLength: 500 },
8305
+ text: { type: "string", maxLength: 2e4 },
8306
+ html: { type: "string", maxLength: 1e5 }
8307
+ }
8308
+ }
8309
+ }
7827
8310
  }
7828
8311
  };
7829
8312
  var Ajv = import_ajv.default;
@@ -7870,23 +8353,53 @@ function validateJsonFormsStepDispatch(tool, knownToolNames) {
7870
8353
  if (!isRecord(xapps) || !("onStepComplete" in xapps)) return;
7871
8354
  const action = xapps.onStepComplete;
7872
8355
  if (!isRecord(action)) {
7873
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete must be an object`), { status: 400 });
8356
+ throw Object.assign(
8357
+ new Error(
8358
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete must be an object`
8359
+ ),
8360
+ { status: 400 }
8361
+ );
7874
8362
  }
7875
8363
  if (String(action.type) !== "request") {
7876
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.type must be "request"`), { status: 400 });
8364
+ throw Object.assign(
8365
+ new Error(
8366
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.type must be "request"`
8367
+ ),
8368
+ { status: 400 }
8369
+ );
7877
8370
  }
7878
8371
  const toolName = String(action.toolName ?? "").trim();
7879
8372
  if (!toolName) {
7880
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.toolName is required`), { status: 400 });
8373
+ throw Object.assign(
8374
+ new Error(
8375
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.toolName is required`
8376
+ ),
8377
+ { status: 400 }
8378
+ );
7881
8379
  }
7882
8380
  if (!knownToolNames.has(toolName)) {
7883
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.toolName references unknown tool: ${toolName}`), { status: 400 });
8381
+ throw Object.assign(
8382
+ new Error(
8383
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.toolName references unknown tool: ${toolName}`
8384
+ ),
8385
+ { status: 400 }
8386
+ );
7884
8387
  }
7885
8388
  if ("payloadMapping" in action && !isRecord(action.payloadMapping)) {
7886
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.payloadMapping must be an object`), { status: 400 });
8389
+ throw Object.assign(
8390
+ new Error(
8391
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.payloadMapping must be an object`
8392
+ ),
8393
+ { status: 400 }
8394
+ );
7887
8395
  }
7888
8396
  if ("resultMapping" in action && !isRecord(action.resultMapping)) {
7889
- throw Object.assign(new Error(`Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.resultMapping must be an object`), { status: 400 });
8397
+ throw Object.assign(
8398
+ new Error(
8399
+ `Tool ${tool.tool_name} input_ui_schema step ${idx + 1} xapps.onStepComplete.resultMapping must be an object`
8400
+ ),
8401
+ { status: 400 }
8402
+ );
7890
8403
  }
7891
8404
  });
7892
8405
  }
@@ -7931,7 +8444,9 @@ function validateLinkingSetupUrl(setupUrl) {
7931
8444
  const allowInsecure = String(process.env.XAPPS_ALLOW_INSECURE_LINKING_URLS || "").trim().toLowerCase();
7932
8445
  const insecureAllowed = allowInsecure === "true" || allowInsecure === "1";
7933
8446
  if (parsed.protocol !== "https:" && !isLoopbackHostname(parsed.hostname) && !insecureAllowed) {
7934
- throw Object.assign(new Error("linking.setup_url must use https unless it targets localhost"), { status: 400 });
8447
+ throw Object.assign(new Error("linking.setup_url must use https unless it targets localhost"), {
8448
+ status: 400
8449
+ });
7935
8450
  }
7936
8451
  const allowlist = parseUrlAllowlist("XAPPS_LINKING_SETUP_URL_ALLOWLIST");
7937
8452
  if (!matchesUrlAllowlist(parsed, allowlist)) {
@@ -7963,7 +8478,12 @@ function validateWidgetResultPresentation(widget) {
7963
8478
  if (rawValue === void 0 || rawValue === null || String(rawValue).trim() === "") continue;
7964
8479
  const normalized = normalizeResultPresentation(rawValue);
7965
8480
  if (normalized === "__invalid__") {
7966
- throw Object.assign(new Error(`Widget ${widget.widget_name} ${fieldPath} must be one of: runtime_default, inline, publisher_managed`), { status: 400 });
8481
+ throw Object.assign(
8482
+ new Error(
8483
+ `Widget ${widget.widget_name} ${fieldPath} must be one of: runtime_default, inline, publisher_managed`
8484
+ ),
8485
+ { status: 400 }
8486
+ );
7967
8487
  }
7968
8488
  }
7969
8489
  }
@@ -7971,9 +8491,17 @@ function validateGuardHookConfig(guard, resolvedConfigOverride) {
7971
8491
  const rawConfig = isPlainObject(guard.config) ? guard.config : null;
7972
8492
  const effectiveConfig = resolvedConfigOverride && isPlainObject(resolvedConfigOverride) ? resolvedConfigOverride : rawConfig;
7973
8493
  if (!effectiveConfig) return;
7974
- const unresolvedNotificationRef = Boolean(rawConfig && readNotificationRef(rawConfig) && !resolvedConfigOverride);
7975
- const unresolvedInvoiceRef = Boolean(rawConfig && readInvoiceRef(rawConfig) && !resolvedConfigOverride);
7976
- const resolved = normalizeHookGuardConfig({ slug: guard.slug, trigger: guard.trigger, config: effectiveConfig });
8494
+ const unresolvedNotificationRef = Boolean(
8495
+ rawConfig && readNotificationRef(rawConfig) && !resolvedConfigOverride
8496
+ );
8497
+ const unresolvedInvoiceRef = Boolean(
8498
+ rawConfig && readInvoiceRef(rawConfig) && !resolvedConfigOverride
8499
+ );
8500
+ const resolved = normalizeHookGuardConfig({
8501
+ slug: guard.slug,
8502
+ trigger: guard.trigger,
8503
+ config: effectiveConfig
8504
+ });
7977
8505
  const effectKind = resolved.config.effectKind;
7978
8506
  const executionMode = resolved.config.executionMode;
7979
8507
  const providerScope = resolved.config.providerScope;
@@ -7982,37 +8510,81 @@ function validateGuardHookConfig(guard, resolvedConfigOverride) {
7982
8510
  const hookMeta = resolved.hook;
7983
8511
  const supportedFieldChecks = [
7984
8512
  ["config.effect_kind", rawConfig?.effect_kind ?? rawConfig?.effectKind],
7985
- ["config.execution_mode", rawConfig?.execution_mode ?? rawConfig?.executionMode],
7986
- ["config.provider_scope", rawConfig?.provider_scope ?? rawConfig?.providerScope],
7987
- ["config.failure_policy", rawConfig?.failure_policy ?? rawConfig?.failurePolicy],
7988
- ["config.idempotency_scope", rawConfig?.idempotency_scope ?? rawConfig?.idempotencyScope]
8513
+ [
8514
+ "config.execution_mode",
8515
+ rawConfig?.execution_mode ?? rawConfig?.executionMode
8516
+ ],
8517
+ [
8518
+ "config.provider_scope",
8519
+ rawConfig?.provider_scope ?? rawConfig?.providerScope
8520
+ ],
8521
+ [
8522
+ "config.failure_policy",
8523
+ rawConfig?.failure_policy ?? rawConfig?.failurePolicy
8524
+ ],
8525
+ [
8526
+ "config.idempotency_scope",
8527
+ rawConfig?.idempotency_scope ?? rawConfig?.idempotencyScope
8528
+ ]
7989
8529
  ];
7990
8530
  for (const [fieldPath, rawValue] of supportedFieldChecks) {
7991
8531
  if (rawValue === void 0 || rawValue === null || String(rawValue).trim() === "") continue;
7992
8532
  if (fieldPath === "config.effect_kind" && !(resolved.config.effectKind || "").trim() || fieldPath === "config.execution_mode" && !(resolved.config.executionMode || "").trim() || fieldPath === "config.provider_scope" && !(resolved.config.providerScope || "").trim() || fieldPath === "config.failure_policy" && !(resolved.config.failurePolicy || "").trim() || fieldPath === "config.idempotency_scope" && !(resolved.config.idempotencyScope || "").trim()) {
7993
- throw Object.assign(new Error(`Guard ${guard.slug} ${fieldPath} has unsupported value: ${String(rawValue)}`), { status: 400 });
8533
+ throw Object.assign(
8534
+ new Error(`Guard ${guard.slug} ${fieldPath} has unsupported value: ${String(rawValue)}`),
8535
+ { status: 400 }
8536
+ );
7994
8537
  }
7995
8538
  }
7996
8539
  if (effectKind && guard.trigger.startsWith("before:") && effectKind !== "policy") {
7997
- throw Object.assign(new Error(`Guard ${guard.slug} effect_kind=${effectKind} is not supported on blocking trigger ${guard.trigger}`), { status: 400 });
8540
+ throw Object.assign(
8541
+ new Error(
8542
+ `Guard ${guard.slug} effect_kind=${effectKind} is not supported on blocking trigger ${guard.trigger}`
8543
+ ),
8544
+ { status: 400 }
8545
+ );
7998
8546
  }
7999
8547
  if (effectKind && hookMeta && !hookMeta.allowedEffectKinds.includes(effectKind)) {
8000
- throw Object.assign(new Error(`Guard ${guard.slug} effect_kind=${effectKind} is not supported on trigger ${guard.trigger}`), { status: 400 });
8548
+ throw Object.assign(
8549
+ new Error(
8550
+ `Guard ${guard.slug} effect_kind=${effectKind} is not supported on trigger ${guard.trigger}`
8551
+ ),
8552
+ { status: 400 }
8553
+ );
8001
8554
  }
8002
8555
  if (effectKind === "policy" && (providerScope || idempotencyScope) && guard.trigger.startsWith("before:")) {
8003
- throw Object.assign(new Error(`Guard ${guard.slug} policy effect on ${guard.trigger} must not declare provider_scope or idempotency_scope`), { status: 400 });
8556
+ throw Object.assign(
8557
+ new Error(
8558
+ `Guard ${guard.slug} policy effect on ${guard.trigger} must not declare provider_scope or idempotency_scope`
8559
+ ),
8560
+ { status: 400 }
8561
+ );
8004
8562
  }
8005
8563
  if (executionMode === "gateway_delegated" && providerScope === "gateway") {
8006
- throw Object.assign(new Error(`Guard ${guard.slug} gateway_delegated execution requires provider_scope tenant or publisher`), { status: 400 });
8564
+ throw Object.assign(
8565
+ new Error(
8566
+ `Guard ${guard.slug} gateway_delegated execution requires provider_scope tenant or publisher`
8567
+ ),
8568
+ { status: 400 }
8569
+ );
8007
8570
  }
8008
8571
  if ((effectKind === "invoice" || effectKind === "notification") && !providerScope && !unresolvedNotificationRef && !unresolvedInvoiceRef) {
8009
- throw Object.assign(new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires provider_scope`), { status: 400 });
8572
+ throw Object.assign(
8573
+ new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires provider_scope`),
8574
+ { status: 400 }
8575
+ );
8010
8576
  }
8011
8577
  if ((effectKind === "invoice" || effectKind === "notification") && !failurePolicy && !unresolvedNotificationRef && !unresolvedInvoiceRef) {
8012
- throw Object.assign(new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires failure_policy`), { status: 400 });
8578
+ throw Object.assign(
8579
+ new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires failure_policy`),
8580
+ { status: 400 }
8581
+ );
8013
8582
  }
8014
8583
  if ((effectKind === "invoice" || effectKind === "notification") && !idempotencyScope && !unresolvedNotificationRef && !unresolvedInvoiceRef) {
8015
- throw Object.assign(new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires idempotency_scope`), { status: 400 });
8584
+ throw Object.assign(
8585
+ new Error(`Guard ${guard.slug} effect_kind=${effectKind} requires idempotency_scope`),
8586
+ { status: 400 }
8587
+ );
8016
8588
  }
8017
8589
  }
8018
8590
  function readPaymentGuardRef(config) {
@@ -8024,31 +8596,48 @@ function validateAdapterShape(tool) {
8024
8596
  if (!adapter || !isPlainObject(adapter)) return;
8025
8597
  const path = String(adapter.path ?? "").trim();
8026
8598
  if (!path.startsWith("/")) {
8027
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.path must start with "/"`), { status: 400 });
8599
+ throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.path must start with "/"`), {
8600
+ status: 400
8601
+ });
8028
8602
  }
8029
8603
  const query = adapter.query;
8030
8604
  if (query !== void 0 && !isPlainObject(query)) {
8031
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.query must be an object`), { status: 400 });
8605
+ throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.query must be an object`), {
8606
+ status: 400
8607
+ });
8032
8608
  }
8033
8609
  const headers = adapter.headers;
8034
8610
  if (headers !== void 0) {
8035
8611
  if (!isPlainObject(headers)) {
8036
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.headers must be an object`), { status: 400 });
8612
+ throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.headers must be an object`), {
8613
+ status: 400
8614
+ });
8037
8615
  }
8038
8616
  for (const headerName of Object.keys(headers)) {
8039
8617
  const trimmed = String(headerName).trim();
8040
8618
  if (!trimmed || !/^[A-Za-z0-9-]+$/.test(trimmed)) {
8041
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.headers has invalid header name: ${headerName}`), { status: 400 });
8619
+ throw Object.assign(
8620
+ new Error(
8621
+ `Tool ${tool.tool_name} adapter.headers has invalid header name: ${headerName}`
8622
+ ),
8623
+ { status: 400 }
8624
+ );
8042
8625
  }
8043
8626
  }
8044
8627
  }
8045
8628
  const responseMapping = adapter.response_mapping;
8046
8629
  if (responseMapping !== void 0) {
8047
8630
  if (!isPlainObject(responseMapping)) {
8048
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.response_mapping must be an object`), { status: 400 });
8631
+ throw Object.assign(
8632
+ new Error(`Tool ${tool.tool_name} adapter.response_mapping must be an object`),
8633
+ { status: 400 }
8634
+ );
8049
8635
  }
8050
8636
  if (Object.keys(responseMapping).length === 0) {
8051
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.response_mapping must not be empty`), { status: 400 });
8637
+ throw Object.assign(
8638
+ new Error(`Tool ${tool.tool_name} adapter.response_mapping must not be empty`),
8639
+ { status: 400 }
8640
+ );
8052
8641
  }
8053
8642
  const outputSchema = isPlainObject(tool.output_schema) ? tool.output_schema : null;
8054
8643
  const schemaType = String(outputSchema?.type ?? "").trim();
@@ -8056,13 +8645,23 @@ function validateAdapterShape(tool) {
8056
8645
  if (schemaType === "object" && schemaProperties) {
8057
8646
  for (const mappedKey of Object.keys(responseMapping)) {
8058
8647
  if (!Object.prototype.hasOwnProperty.call(schemaProperties, mappedKey)) {
8059
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.response_mapping key "${mappedKey}" is not declared in output_schema.properties`), { status: 400 });
8648
+ throw Object.assign(
8649
+ new Error(
8650
+ `Tool ${tool.tool_name} adapter.response_mapping key "${mappedKey}" is not declared in output_schema.properties`
8651
+ ),
8652
+ { status: 400 }
8653
+ );
8060
8654
  }
8061
8655
  }
8062
8656
  const required = Array.isArray(outputSchema?.required) ? outputSchema.required.map((v) => String(v || "").trim()).filter(Boolean) : [];
8063
8657
  for (const requiredField of required) {
8064
8658
  if (!Object.prototype.hasOwnProperty.call(responseMapping, requiredField)) {
8065
- throw Object.assign(new Error(`Tool ${tool.tool_name} adapter.response_mapping must include required output field "${requiredField}"`), { status: 400 });
8659
+ throw Object.assign(
8660
+ new Error(
8661
+ `Tool ${tool.tool_name} adapter.response_mapping must include required output field "${requiredField}"`
8662
+ ),
8663
+ { status: 400 }
8664
+ );
8066
8665
  }
8067
8666
  }
8068
8667
  }
@@ -8070,7 +8669,10 @@ function validateAdapterShape(tool) {
8070
8669
  }
8071
8670
  function parseXappManifest(input, options) {
8072
8671
  if (!validate(input)) {
8073
- throw Object.assign(new Error("Invalid manifest"), { status: 400, details: validate.errors ?? null });
8672
+ throw Object.assign(new Error("Invalid manifest"), {
8673
+ status: 400,
8674
+ details: validate.errors ?? null
8675
+ });
8074
8676
  }
8075
8677
  const manifest = input;
8076
8678
  const paymentDefinitions = Array.isArray(manifest.payment_guard_definitions) ? manifest.payment_guard_definitions : [];
@@ -8096,8 +8698,10 @@ function parseXappManifest(input, options) {
8096
8698
  const [definitions, names, label] = list;
8097
8699
  for (const def of definitions) {
8098
8700
  const name = String(def?.name ?? "").trim();
8099
- if (!name) throw Object.assign(new Error(`${label} entries require non-empty name`), { status: 400 });
8100
- if (names.has(name)) throw Object.assign(new Error(`Duplicate ${label} name: ${name}`), { status: 400 });
8701
+ if (!name)
8702
+ throw Object.assign(new Error(`${label} entries require non-empty name`), { status: 400 });
8703
+ if (names.has(name))
8704
+ throw Object.assign(new Error(`Duplicate ${label} name: ${name}`), { status: 400 });
8101
8705
  names.add(name);
8102
8706
  }
8103
8707
  }
@@ -8116,19 +8720,32 @@ function parseXappManifest(input, options) {
8116
8720
  for (const [groupName, group] of Object.entries(manifest.endpoint_groups)) {
8117
8721
  for (const member of group.members) {
8118
8722
  if (!endpointNames.has(member)) {
8119
- throw Object.assign(new Error(`Endpoint group ${groupName} references unknown endpoint: ${member}`), { status: 400 });
8723
+ throw Object.assign(
8724
+ new Error(`Endpoint group ${groupName} references unknown endpoint: ${member}`),
8725
+ { status: 400 }
8726
+ );
8120
8727
  }
8121
8728
  }
8122
8729
  }
8123
8730
  }
8124
- const knownToolNames = new Set((manifest.tools ?? []).map((tool) => String(tool.tool_name || "").trim()));
8731
+ const knownToolNames = new Set(
8732
+ (manifest.tools ?? []).map((tool) => String(tool.tool_name || "").trim())
8733
+ );
8125
8734
  const referencedPaymentDefinitionNames = /* @__PURE__ */ new Set();
8126
8735
  const referencedSubjectProfileDefinitionNames = /* @__PURE__ */ new Set();
8127
- const notificationDefinitionRegistry = buildNotificationDefinitionRegistry(manifest.notification_definitions ?? []);
8128
- const notificationTemplateRegistry = buildNotificationTemplateRegistry(manifest.notification_templates ?? []);
8129
- const invoiceDefinitionRegistry = buildInvoiceDefinitionRegistry(manifest.invoice_definitions ?? []);
8736
+ const notificationDefinitionRegistry = buildNotificationDefinitionRegistry(
8737
+ manifest.notification_definitions ?? []
8738
+ );
8739
+ const notificationTemplateRegistry = buildNotificationTemplateRegistry(
8740
+ manifest.notification_templates ?? []
8741
+ );
8742
+ const invoiceDefinitionRegistry = buildInvoiceDefinitionRegistry(
8743
+ manifest.invoice_definitions ?? []
8744
+ );
8130
8745
  const invoiceTemplateRegistry = buildInvoiceTemplateRegistry(manifest.invoice_templates ?? []);
8131
- const subjectProfileDefinitionRegistry = buildSubjectProfileDefinitionRegistry(manifest.subject_profile_guard_definitions ?? []);
8746
+ const subjectProfileDefinitionRegistry = buildSubjectProfileDefinitionRegistry(
8747
+ manifest.subject_profile_guard_definitions ?? []
8748
+ );
8132
8749
  const referencedNotificationDefinitionNames = /* @__PURE__ */ new Set();
8133
8750
  const referencedNotificationTemplateNames = /* @__PURE__ */ new Set();
8134
8751
  const referencedInvoiceDefinitionNames = /* @__PURE__ */ new Set();
@@ -8138,7 +8755,12 @@ function parseXappManifest(input, options) {
8138
8755
  if (!templateRef) continue;
8139
8756
  referencedNotificationTemplateNames.add(templateRef);
8140
8757
  if (!notificationTemplateRegistry.has(templateRef)) {
8141
- throw Object.assign(new Error(`notification_definitions entry ${String(def?.name ?? "unknown")} references unknown template_ref: ${templateRef}`), { status: 400 });
8758
+ throw Object.assign(
8759
+ new Error(
8760
+ `notification_definitions entry ${String(def?.name ?? "unknown")} references unknown template_ref: ${templateRef}`
8761
+ ),
8762
+ { status: 400 }
8763
+ );
8142
8764
  }
8143
8765
  }
8144
8766
  for (const def of invoiceDefinitions) {
@@ -8146,7 +8768,12 @@ function parseXappManifest(input, options) {
8146
8768
  if (!templateRef) continue;
8147
8769
  referencedInvoiceTemplateNames.add(templateRef);
8148
8770
  if (!invoiceTemplateRegistry.has(templateRef)) {
8149
- throw Object.assign(new Error(`invoice_definitions entry ${String(def?.name ?? "unknown")} references unknown invoice_template_ref: ${templateRef}`), { status: 400 });
8771
+ throw Object.assign(
8772
+ new Error(
8773
+ `invoice_definitions entry ${String(def?.name ?? "unknown")} references unknown invoice_template_ref: ${templateRef}`
8774
+ ),
8775
+ { status: 400 }
8776
+ );
8150
8777
  }
8151
8778
  }
8152
8779
  for (const widget of manifest.widgets ?? []) validateWidgetResultPresentation(widget);
@@ -8163,18 +8790,33 @@ function parseXappManifest(input, options) {
8163
8790
  manifest.endpoints && isRecord(manifest.endpoints) ? Object.keys(manifest.endpoints) : []
8164
8791
  );
8165
8792
  if (!endpointNames.has(endpointRef)) {
8166
- throw Object.assign(new Error(`Tool ${tool.tool_name} dispatch_policy.endpoint_ref references unknown endpoint: ${endpointRef}`), { status: 400 });
8793
+ throw Object.assign(
8794
+ new Error(
8795
+ `Tool ${tool.tool_name} dispatch_policy.endpoint_ref references unknown endpoint: ${endpointRef}`
8796
+ ),
8797
+ { status: 400 }
8798
+ );
8167
8799
  }
8168
8800
  }
8169
8801
  const requiredPolicyFields = Array.isArray(policy.required_policy_fields) ? policy.required_policy_fields : [];
8170
8802
  const normalizedRequired = requiredPolicyFields.map((v) => normalizeDispatchPolicyFieldName(String(v ?? ""))).filter(Boolean);
8171
8803
  for (const field of normalizedRequired) {
8172
8804
  if (!CANONICAL_REQUIRED_POLICY_FIELDS.has(field)) {
8173
- throw Object.assign(new Error(`Tool ${tool.tool_name} dispatch_policy.required_policy_fields contains unknown policy field: ${field}`), { status: 400 });
8805
+ throw Object.assign(
8806
+ new Error(
8807
+ `Tool ${tool.tool_name} dispatch_policy.required_policy_fields contains unknown policy field: ${field}`
8808
+ ),
8809
+ { status: 400 }
8810
+ );
8174
8811
  }
8175
8812
  }
8176
8813
  if (new Set(normalizedRequired).size !== normalizedRequired.length) {
8177
- throw Object.assign(new Error(`Tool ${tool.tool_name} dispatch_policy.required_policy_fields contains duplicates after normalization`), { status: 400 });
8814
+ throw Object.assign(
8815
+ new Error(
8816
+ `Tool ${tool.tool_name} dispatch_policy.required_policy_fields contains duplicates after normalization`
8817
+ ),
8818
+ { status: 400 }
8819
+ );
8178
8820
  }
8179
8821
  validateJsonFormsStepDispatch(tool, knownToolNames);
8180
8822
  }
@@ -8197,7 +8839,11 @@ function parseXappManifest(input, options) {
8197
8839
  source: "consumer_manifest",
8198
8840
  templates: notificationTemplateRegistry
8199
8841
  });
8200
- if (!resolved.ok) throw Object.assign(new Error(resolved.message), { status: 400, details: resolved.details });
8842
+ if (!resolved.ok)
8843
+ throw Object.assign(new Error(resolved.message), {
8844
+ status: 400,
8845
+ details: resolved.details
8846
+ });
8201
8847
  return resolved.config;
8202
8848
  })() : null;
8203
8849
  const resolvedInvoiceConfig = invoiceRef && invoiceDefinitionRegistry.has(invoiceRef) ? (() => {
@@ -8207,7 +8853,11 @@ function parseXappManifest(input, options) {
8207
8853
  source: "consumer_manifest",
8208
8854
  templates: invoiceTemplateRegistry
8209
8855
  });
8210
- if (!resolved.ok) throw Object.assign(new Error(resolved.message), { status: 400, details: resolved.details });
8856
+ if (!resolved.ok)
8857
+ throw Object.assign(new Error(resolved.message), {
8858
+ status: 400,
8859
+ details: resolved.details
8860
+ });
8211
8861
  return resolved.config;
8212
8862
  })() : null;
8213
8863
  const resolvedHookFamilyConfig = resolvedNotificationConfig ?? resolvedInvoiceConfig;
@@ -8215,14 +8865,24 @@ function parseXappManifest(input, options) {
8215
8865
  if (templateRef) {
8216
8866
  referencedNotificationTemplateNames.add(templateRef);
8217
8867
  if (!notificationTemplateRegistry.has(templateRef)) {
8218
- throw Object.assign(new Error(`Guard ${String(guard?.slug || "unknown")} references unknown template_ref: ${templateRef}`), { status: 400 });
8868
+ throw Object.assign(
8869
+ new Error(
8870
+ `Guard ${String(guard?.slug || "unknown")} references unknown template_ref: ${templateRef}`
8871
+ ),
8872
+ { status: 400 }
8873
+ );
8219
8874
  }
8220
8875
  }
8221
8876
  const invoiceTemplateRef = resolvedInvoiceConfig && isRecord(resolvedInvoiceConfig) ? readInvoiceTemplateRef(resolvedInvoiceConfig) : readInvoiceTemplateRef(guardConfig);
8222
8877
  if (invoiceTemplateRef) {
8223
8878
  referencedInvoiceTemplateNames.add(invoiceTemplateRef);
8224
8879
  if (!invoiceTemplateRegistry.has(invoiceTemplateRef)) {
8225
- throw Object.assign(new Error(`Guard ${String(guard?.slug || "unknown")} references unknown invoice_template_ref: ${invoiceTemplateRef}`), { status: 400 });
8880
+ throw Object.assign(
8881
+ new Error(
8882
+ `Guard ${String(guard?.slug || "unknown")} references unknown invoice_template_ref: ${invoiceTemplateRef}`
8883
+ ),
8884
+ { status: 400 }
8885
+ );
8226
8886
  }
8227
8887
  }
8228
8888
  validateGuardHookConfig(guard, resolvedHookFamilyConfig);
@@ -8232,7 +8892,11 @@ function parseXappManifest(input, options) {
8232
8892
  definition: subjectProfileDefinitionRegistry.get(subjectProfileGuardRef),
8233
8893
  source: "consumer_manifest"
8234
8894
  });
8235
- if (!resolved.ok) throw Object.assign(new Error(`Guard ${guardSlug}: ${resolved.message}`), { status: 400, details: resolved.details });
8895
+ if (!resolved.ok)
8896
+ throw Object.assign(new Error(`Guard ${guardSlug}: ${resolved.message}`), {
8897
+ status: 400,
8898
+ details: resolved.details
8899
+ });
8236
8900
  return resolved.config;
8237
8901
  })() : null;
8238
8902
  const subjectProfileRequirement = resolveSubjectProfileRequirement(
@@ -8240,7 +8904,10 @@ function parseXappManifest(input, options) {
8240
8904
  );
8241
8905
  const expectsSubjectProfileContract = guardSlug === "subject-profile-check" || explicitPolicyKind === "subject_profile" || explicitPolicyKind === "subject-profile" || subjectProfileRequirement.ok && subjectProfileRequirement.source !== "none";
8242
8906
  if (expectsSubjectProfileContract && !subjectProfileRequirement.ok) {
8243
- throw Object.assign(new Error(`Guard ${guardSlug}: ${subjectProfileRequirement.message}`), { status: 400, details: subjectProfileRequirement.details });
8907
+ throw Object.assign(new Error(`Guard ${guardSlug}: ${subjectProfileRequirement.message}`), {
8908
+ status: 400,
8909
+ details: subjectProfileRequirement.details
8910
+ });
8244
8911
  }
8245
8912
  const ref = readPaymentGuardRef(guardConfig);
8246
8913
  if (!ref) continue;
@@ -8250,7 +8917,10 @@ function parseXappManifest(input, options) {
8250
8917
  String(guardConfig.tool_name ?? guardConfig.toolName ?? "").trim()
8251
8918
  );
8252
8919
  if (hasExplicitTool) continue;
8253
- throw Object.assign(new Error(`Guard ${guardSlug} references unknown payment_guard_ref: ${ref}`), { status: 400 });
8920
+ throw Object.assign(
8921
+ new Error(`Guard ${guardSlug} references unknown payment_guard_ref: ${ref}`),
8922
+ { status: 400 }
8923
+ );
8254
8924
  }
8255
8925
  }
8256
8926
  const emitWarning = options?.warn;
@@ -8258,34 +8928,61 @@ function parseXappManifest(input, options) {
8258
8928
  if (process.env.NODE_ENV === "test") return;
8259
8929
  emitWarning?.({ kind, details });
8260
8930
  };
8261
- const unreferencedPaymentDefinitions = Array.from(paymentDefinitionNames).filter((name) => !referencedPaymentDefinitionNames.has(name));
8931
+ const unreferencedPaymentDefinitions = Array.from(paymentDefinitionNames).filter(
8932
+ (name) => !referencedPaymentDefinitionNames.has(name)
8933
+ );
8262
8934
  if (referencedPaymentDefinitionNames.size > 0 && unreferencedPaymentDefinitions.length > 0) {
8263
- warnIfNeeded("unreferenced_payment_guard_definitions", { definitions: unreferencedPaymentDefinitions });
8935
+ warnIfNeeded("unreferenced_payment_guard_definitions", {
8936
+ definitions: unreferencedPaymentDefinitions
8937
+ });
8264
8938
  }
8265
- const unreferencedSubjectProfileDefinitions = Array.from(subjectProfileDefinitionNames).filter((name) => !referencedSubjectProfileDefinitionNames.has(name));
8939
+ const unreferencedSubjectProfileDefinitions = Array.from(subjectProfileDefinitionNames).filter(
8940
+ (name) => !referencedSubjectProfileDefinitionNames.has(name)
8941
+ );
8266
8942
  if (referencedSubjectProfileDefinitionNames.size > 0 && unreferencedSubjectProfileDefinitions.length > 0) {
8267
- warnIfNeeded("unreferenced_subject_profile_guard_definitions", { definitions: unreferencedSubjectProfileDefinitions });
8943
+ warnIfNeeded("unreferenced_subject_profile_guard_definitions", {
8944
+ definitions: unreferencedSubjectProfileDefinitions
8945
+ });
8268
8946
  }
8269
- const unreferencedNotificationDefinitions = Array.from(notificationDefinitionNames).filter((name) => !referencedNotificationDefinitionNames.has(name));
8947
+ const unreferencedNotificationDefinitions = Array.from(notificationDefinitionNames).filter(
8948
+ (name) => !referencedNotificationDefinitionNames.has(name)
8949
+ );
8270
8950
  if (referencedNotificationDefinitionNames.size > 0 && unreferencedNotificationDefinitions.length > 0) {
8271
- warnIfNeeded("unreferenced_notification_definitions", { definitions: unreferencedNotificationDefinitions });
8951
+ warnIfNeeded("unreferenced_notification_definitions", {
8952
+ definitions: unreferencedNotificationDefinitions
8953
+ });
8272
8954
  }
8273
- const unreferencedNotificationTemplates = Array.from(notificationTemplateNames).filter((name) => !referencedNotificationTemplateNames.has(name));
8955
+ const unreferencedNotificationTemplates = Array.from(notificationTemplateNames).filter(
8956
+ (name) => !referencedNotificationTemplateNames.has(name)
8957
+ );
8274
8958
  if (notificationTemplateNames.size > 0 && unreferencedNotificationTemplates.length > 0) {
8275
- warnIfNeeded("unreferenced_notification_templates", { templates: unreferencedNotificationTemplates });
8959
+ warnIfNeeded("unreferenced_notification_templates", {
8960
+ templates: unreferencedNotificationTemplates
8961
+ });
8276
8962
  }
8277
- const unreferencedInvoiceDefinitions = Array.from(invoiceDefinitionNames).filter((name) => !referencedInvoiceDefinitionNames.has(name));
8963
+ const unreferencedInvoiceDefinitions = Array.from(invoiceDefinitionNames).filter(
8964
+ (name) => !referencedInvoiceDefinitionNames.has(name)
8965
+ );
8278
8966
  if (referencedInvoiceDefinitionNames.size > 0 && unreferencedInvoiceDefinitions.length > 0) {
8279
- warnIfNeeded("unreferenced_invoice_definitions", { definitions: unreferencedInvoiceDefinitions });
8967
+ warnIfNeeded("unreferenced_invoice_definitions", {
8968
+ definitions: unreferencedInvoiceDefinitions
8969
+ });
8280
8970
  }
8281
- const unreferencedInvoiceTemplates = Array.from(invoiceTemplateNames).filter((name) => !referencedInvoiceTemplateNames.has(name));
8971
+ const unreferencedInvoiceTemplates = Array.from(invoiceTemplateNames).filter(
8972
+ (name) => !referencedInvoiceTemplateNames.has(name)
8973
+ );
8282
8974
  if (invoiceTemplateNames.size > 0 && unreferencedInvoiceTemplates.length > 0) {
8283
8975
  warnIfNeeded("unreferenced_invoice_templates", { templates: unreferencedInvoiceTemplates });
8284
8976
  }
8285
8977
  return manifest;
8286
8978
  }
8287
8979
  export {
8980
+ getManifestLocaleCandidates,
8981
+ normalizeManifestLocale,
8288
8982
  parseXappManifest,
8983
+ resolveInvoiceTemplateVariant,
8984
+ resolveManifestLocalizedText,
8985
+ resolveNotificationTemplateVariant,
8289
8986
  xappManifestJsonSchema
8290
8987
  };
8291
8988
  //# sourceMappingURL=index.js.map