@xapps-platform/backend-kit 0.1.5 → 0.2.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/README.md CHANGED
@@ -33,6 +33,67 @@ override seams, while keeping the later shared tenant/publisher direction
33
33
  open. The current shipped reference consumers are still tenant backends, but
34
34
  the package direction is actor-agnostic where possible.
35
35
 
36
+ For request-capable publisher-rendered widgets, use the package layer to
37
+ verify browser widget context server-side before exposing private runtime
38
+ behavior:
39
+
40
+ ```ts
41
+ import {
42
+ evaluateWidgetBootstrapOriginPolicy,
43
+ verifyBrowserWidgetContext,
44
+ } from "@xapps-platform/backend-kit";
45
+
46
+ const originPolicy = evaluateWidgetBootstrapOriginPolicy({
47
+ hostOrigin: request.body?.hostOrigin,
48
+ allowedOrigins: config.widgetBootstrap.allowedOrigins,
49
+ });
50
+
51
+ if (!originPolicy.ok) {
52
+ reply.code(originPolicy.code === "HOST_ORIGIN_REQUIRED" ? 400 : 403).send({
53
+ ok: false,
54
+ error: {
55
+ code: originPolicy.code,
56
+ message: originPolicy.message,
57
+ },
58
+ });
59
+ return;
60
+ }
61
+
62
+ const verified = await verifyBrowserWidgetContext(gatewayClient, {
63
+ hostOrigin: originPolicy.hostOrigin,
64
+ installationId: "inst_123",
65
+ bindToolName: "submit_form",
66
+ subjectId: "sub_123",
67
+ bootstrapTicket: request.body?.bootstrapTicket ?? null,
68
+ });
69
+ ```
70
+
71
+ Recommended shared local config contract for publisher-rendered bootstrap
72
+ routes:
73
+
74
+ - `widgetBootstrap.allowedOrigins`
75
+ - optional app env:
76
+ - `XAPPS_WIDGET_ALLOWED_ORIGINS=https://host.example.test,https://host-b.example.test`
77
+
78
+ This stays local/app-owned on purpose. The package helper standardizes the
79
+ policy behavior without forcing a repo-wide env parser or backend shape.
80
+
81
+ Recommended request-widget posture:
82
+
83
+ - treat the widget asset URL as a public/bootstrap shell
84
+ - keep request-capable UI blocked until widget context is verified server-side
85
+ - do not place private keys, secrets, or durable bearer tokens in `entry.url`
86
+ - direct raw browser hits should stay blocked instead of unlocking private runtime
87
+
88
+ Optional stronger bootstrap transport already supported:
89
+
90
+ - `widgets[].config.xapps.bootstrap_transport = "signed_ticket"`
91
+ - current first slice reuses the short-lived signed widget token as a bootstrap
92
+ ticket and carries it in the iframe URL hash
93
+ - browser widget code can forward it to your backend as `bootstrapTicket`
94
+ - the backend kit verification passthrough accepts that field without changing
95
+ the current default/public bootstrap contract
96
+
36
97
  This is now a real package, not a placeholder or extraction stub. Keep the
37
98
  public entry surface stable and split internal package code behind it.
38
99
 
@@ -76,6 +137,7 @@ The current package surface provides:
76
137
  - default mode tree
77
138
  - payment runtime assembly
78
139
  - host-proxy service assembly
140
+ - request-widget bootstrap verification passthrough
79
141
  - subject-profile sourcing hooks
80
142
 
81
143
  Internal package structure is intentionally modular:
package/dist/index.d.ts CHANGED
@@ -44,6 +44,34 @@ export type BackendKit = {
44
44
  registerRoutes: (app: RegisterableApp) => Promise<void>;
45
45
  applyNotFoundHandler: (app: RegisterableApp) => void;
46
46
  };
47
+ export type VerifyBrowserWidgetContextInput = {
48
+ hostOrigin: string;
49
+ bootstrapTicket?: string | null;
50
+ installationId?: string | null;
51
+ bindToolName?: string | null;
52
+ toolName?: string | null;
53
+ subjectId?: string | null;
54
+ };
55
+ export type WidgetBootstrapOriginPolicyInput = {
56
+ hostOrigin: string | null | undefined;
57
+ allowedOrigins?: string[] | string | null | undefined;
58
+ };
59
+ export type WidgetBootstrapOriginPolicyResult = {
60
+ ok: true;
61
+ hostOrigin: string;
62
+ allowedOrigins: string[];
63
+ } | {
64
+ ok: false;
65
+ code: "HOST_ORIGIN_REQUIRED" | "HOST_ORIGIN_NOT_ALLOWED";
66
+ message: string;
67
+ hostOrigin: string | null;
68
+ allowedOrigins: string[];
69
+ };
70
+ export declare function normalizeWidgetBootstrapAllowedOrigins(value: string[] | string | null | undefined): string[];
71
+ export declare function evaluateWidgetBootstrapOriginPolicy(input: WidgetBootstrapOriginPolicyInput): WidgetBootstrapOriginPolicyResult;
72
+ export declare function verifyBrowserWidgetContext(gatewayClient: {
73
+ verifyBrowserWidgetContext: (input: VerifyBrowserWidgetContextInput) => Promise<Record<string, unknown>>;
74
+ }, input: VerifyBrowserWidgetContextInput): Promise<Record<string, unknown>>;
47
75
  export declare function createBackendKit(input?: StringRecord, deps?: BackendKitDeps): Promise<BackendKit>;
48
76
  export { buildHostedGatewayPaymentUrl as buildHostedGatewayPaymentUrl, buildModeHostedGatewayPaymentUrl as buildModeHostedGatewayPaymentUrl, createGatewayExecutionModule, createHostReferenceModule, createReferenceSurfaceModule, createHostProxyService, createPaymentEvidenceHandler, createPaymentRuntime, extractHostedPaymentSessionId, normalizeBackendKitOptions, registerPaymentPageApiRoutes, registerPaymentPageAssetRoute, resolvePlatformSecretRefFromEnv, };
49
77
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -17,6 +17,52 @@ import {
17
17
  normalizeBackendKitOptions,
18
18
  resolvePlatformSecretRefFromEnv
19
19
  } from "./backend/options.js";
20
+ function normalizeOrigin(value) {
21
+ const raw = String(value || "").trim();
22
+ if (!raw) return null;
23
+ try {
24
+ const parsed = new URL(raw);
25
+ if (!parsed.protocol || !parsed.host) return null;
26
+ return parsed.origin;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ function normalizeWidgetBootstrapAllowedOrigins(value) {
32
+ const entries = Array.isArray(value) ? value : String(value || "").split(/[,\n]/);
33
+ const normalized = entries.map((entry) => normalizeOrigin(entry)).filter((entry) => Boolean(entry));
34
+ return Array.from(new Set(normalized));
35
+ }
36
+ function evaluateWidgetBootstrapOriginPolicy(input) {
37
+ const hostOrigin = normalizeOrigin(input.hostOrigin);
38
+ const allowedOrigins = normalizeWidgetBootstrapAllowedOrigins(input.allowedOrigins);
39
+ if (!hostOrigin) {
40
+ return {
41
+ ok: false,
42
+ code: "HOST_ORIGIN_REQUIRED",
43
+ message: "Host origin is required to verify browser widget context",
44
+ hostOrigin: null,
45
+ allowedOrigins
46
+ };
47
+ }
48
+ if (allowedOrigins.length > 0 && !allowedOrigins.includes(hostOrigin)) {
49
+ return {
50
+ ok: false,
51
+ code: "HOST_ORIGIN_NOT_ALLOWED",
52
+ message: "Host origin is not allowed for widget bootstrap verification",
53
+ hostOrigin,
54
+ allowedOrigins
55
+ };
56
+ }
57
+ return {
58
+ ok: true,
59
+ hostOrigin,
60
+ allowedOrigins
61
+ };
62
+ }
63
+ async function verifyBrowserWidgetContext(gatewayClient, input) {
64
+ return gatewayClient.verifyBrowserWidgetContext(input);
65
+ }
20
66
  async function createBackendKit(input = {}, deps = {}) {
21
67
  const normalizeOptions = typeof deps.normalizeOptions === "function" ? deps.normalizeOptions : null;
22
68
  const createReferenceSurfaceModuleDep = typeof deps.createReferenceSurfaceModule === "function" ? deps.createReferenceSurfaceModule : null;
@@ -75,10 +121,13 @@ export {
75
121
  createPaymentEvidenceHandler,
76
122
  createPaymentRuntime,
77
123
  createReferenceSurfaceModule,
124
+ evaluateWidgetBootstrapOriginPolicy,
78
125
  extractHostedPaymentSessionId,
79
126
  normalizeBackendKitOptions,
127
+ normalizeWidgetBootstrapAllowedOrigins,
80
128
  registerPaymentPageApiRoutes,
81
129
  registerPaymentPageAssetRoute,
82
- resolvePlatformSecretRefFromEnv
130
+ resolvePlatformSecretRefFromEnv,
131
+ verifyBrowserWidgetContext
83
132
  };
84
133
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import {\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n} from \"./backend/modules.js\";\nimport {\n buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n} from \"./backend/paymentRuntime.js\";\nimport {\n normalizeBackendKitOptions,\n resolvePlatformSecretRefFromEnv,\n type BackendKitNormalizedOptions,\n type StringRecord,\n} from \"./backend/options.js\";\n\ntype ReplyLike = {\n code: (statusCode: number) => {\n send: (payload: unknown) => unknown;\n };\n};\n\ntype RegisterableApp = {\n setNotFoundHandler: (\n handler: (request: unknown, reply: ReplyLike) => Promise<unknown> | unknown,\n ) => void;\n};\n\ntype RouteModule = {\n registerRoutes: (app: RegisterableApp) => Promise<void> | void;\n};\n\ntype BackendKitDeps = {\n normalizeOptions?: (input: StringRecord) => BackendKitNormalizedOptions;\n createReferenceSurfaceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n enableReference: boolean;\n enableLifecycle: boolean;\n enableBridge: boolean;\n enabledModes: string[];\n reference: BackendKitNormalizedOptions[\"reference\"];\n }) => RouteModule;\n createHostReferenceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n reference: BackendKitNormalizedOptions[\"reference\"];\n enableLifecycle: boolean;\n enableBridge: boolean;\n allowedOrigins: string[];\n bootstrap: BackendKitNormalizedOptions[\"host\"][\"bootstrap\"];\n hostProxyService: unknown;\n }) => RouteModule;\n createGatewayExecutionModule?: (input: {\n enabledModes: string[];\n subjectProfiles: BackendKitNormalizedOptions[\"subjectProfiles\"];\n paymentRuntime: unknown;\n }) => RouteModule;\n};\n\nexport type BackendKit = {\n options: BackendKitNormalizedOptions;\n registerRoutes: (app: RegisterableApp) => Promise<void>;\n applyNotFoundHandler: (app: RegisterableApp) => void;\n};\n\nexport async function createBackendKit(\n input: StringRecord = {},\n deps: BackendKitDeps = {},\n): Promise<BackendKit> {\n const normalizeOptions =\n typeof deps.normalizeOptions === \"function\" ? deps.normalizeOptions : null;\n const createReferenceSurfaceModuleDep =\n typeof deps.createReferenceSurfaceModule === \"function\"\n ? deps.createReferenceSurfaceModule\n : null;\n const createHostReferenceModuleDep =\n typeof deps.createHostReferenceModule === \"function\" ? deps.createHostReferenceModule : null;\n const createGatewayExecutionModuleDep =\n typeof deps.createGatewayExecutionModule === \"function\"\n ? deps.createGatewayExecutionModule\n : null;\n if (\n !normalizeOptions ||\n !createReferenceSurfaceModuleDep ||\n !createHostReferenceModuleDep ||\n !createGatewayExecutionModuleDep\n ) {\n throw new TypeError(\"backend kit dependencies are incomplete\");\n }\n\n const options = normalizeOptions(input);\n const paymentRuntime = await createPaymentRuntime(options, deps);\n\n const referenceSurfaceModule = createReferenceSurfaceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n enableReference: options.host.enableReference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n enabledModes: options.payments.enabledModes,\n reference: options.reference,\n });\n const hostReferenceModule = createHostReferenceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n reference: options.reference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n allowedOrigins: options.host.allowedOrigins,\n bootstrap: options.host.bootstrap,\n hostProxyService: options.overrides.hostProxyService,\n });\n const gatewayExecutionModule = createGatewayExecutionModuleDep({\n enabledModes: options.payments.enabledModes,\n subjectProfiles: options.subjectProfiles,\n paymentRuntime,\n });\n\n return {\n options,\n async registerRoutes(app) {\n await referenceSurfaceModule.registerRoutes(app);\n await hostReferenceModule.registerRoutes(app);\n await gatewayExecutionModule.registerRoutes(app);\n },\n applyNotFoundHandler(app) {\n app.setNotFoundHandler(async (_request, reply) =>\n reply.code(404).send({ message: \"Not found\" }),\n );\n },\n };\n}\n\nexport {\n buildHostedGatewayPaymentUrl as buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl as buildModeHostedGatewayPaymentUrl,\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n normalizeBackendKitOptions,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n resolvePlatformSecretRefFromEnv,\n};\n"],
5
- "mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAoDP,eAAsB,iBACpB,QAAsB,CAAC,GACvB,OAAuB,CAAC,GACH;AACrB,QAAM,mBACJ,OAAO,KAAK,qBAAqB,aAAa,KAAK,mBAAmB;AACxE,QAAM,kCACJ,OAAO,KAAK,iCAAiC,aACzC,KAAK,+BACL;AACN,QAAM,+BACJ,OAAO,KAAK,8BAA8B,aAAa,KAAK,4BAA4B;AAC1F,QAAM,kCACJ,OAAO,KAAK,iCAAiC,aACzC,KAAK,+BACL;AACN,MACE,CAAC,oBACD,CAAC,mCACD,CAAC,gCACD,CAAC,iCACD;AACA,UAAM,IAAI,UAAU,yCAAyC;AAAA,EAC/D;AAEA,QAAM,UAAU,iBAAiB,KAAK;AACtC,QAAM,iBAAiB,MAAM,qBAAqB,SAAS,IAAI;AAE/D,QAAM,yBAAyB,gCAAgC;AAAA,IAC7D,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,cAAc,QAAQ,KAAK;AAAA,IAC3B,cAAc,QAAQ,SAAS;AAAA,IAC/B,WAAW,QAAQ;AAAA,EACrB,CAAC;AACD,QAAM,sBAAsB,6BAA6B;AAAA,IACvD,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,iBAAiB,QAAQ,KAAK;AAAA,IAC9B,cAAc,QAAQ,KAAK;AAAA,IAC3B,gBAAgB,QAAQ,KAAK;AAAA,IAC7B,WAAW,QAAQ,KAAK;AAAA,IACxB,kBAAkB,QAAQ,UAAU;AAAA,EACtC,CAAC;AACD,QAAM,yBAAyB,gCAAgC;AAAA,IAC7D,cAAc,QAAQ,SAAS;AAAA,IAC/B,iBAAiB,QAAQ;AAAA,IACzB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM,eAAe,KAAK;AACxB,YAAM,uBAAuB,eAAe,GAAG;AAC/C,YAAM,oBAAoB,eAAe,GAAG;AAC5C,YAAM,uBAAuB,eAAe,GAAG;AAAA,IACjD;AAAA,IACA,qBAAqB,KAAK;AACxB,UAAI;AAAA,QAAmB,OAAO,UAAU,UACtC,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,SAAS,YAAY,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import {\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n} from \"./backend/modules.js\";\nimport {\n buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n} from \"./backend/paymentRuntime.js\";\nimport {\n normalizeBackendKitOptions,\n resolvePlatformSecretRefFromEnv,\n type BackendKitNormalizedOptions,\n type StringRecord,\n} from \"./backend/options.js\";\n\ntype ReplyLike = {\n code: (statusCode: number) => {\n send: (payload: unknown) => unknown;\n };\n};\n\ntype RegisterableApp = {\n setNotFoundHandler: (\n handler: (request: unknown, reply: ReplyLike) => Promise<unknown> | unknown,\n ) => void;\n};\n\ntype RouteModule = {\n registerRoutes: (app: RegisterableApp) => Promise<void> | void;\n};\n\ntype BackendKitDeps = {\n normalizeOptions?: (input: StringRecord) => BackendKitNormalizedOptions;\n createReferenceSurfaceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n enableReference: boolean;\n enableLifecycle: boolean;\n enableBridge: boolean;\n enabledModes: string[];\n reference: BackendKitNormalizedOptions[\"reference\"];\n }) => RouteModule;\n createHostReferenceModule?: (input: {\n gateway: BackendKitNormalizedOptions[\"gateway\"];\n branding: BackendKitNormalizedOptions[\"branding\"];\n reference: BackendKitNormalizedOptions[\"reference\"];\n enableLifecycle: boolean;\n enableBridge: boolean;\n allowedOrigins: string[];\n bootstrap: BackendKitNormalizedOptions[\"host\"][\"bootstrap\"];\n hostProxyService: unknown;\n }) => RouteModule;\n createGatewayExecutionModule?: (input: {\n enabledModes: string[];\n subjectProfiles: BackendKitNormalizedOptions[\"subjectProfiles\"];\n paymentRuntime: unknown;\n }) => RouteModule;\n};\n\nexport type BackendKit = {\n options: BackendKitNormalizedOptions;\n registerRoutes: (app: RegisterableApp) => Promise<void>;\n applyNotFoundHandler: (app: RegisterableApp) => void;\n};\n\nexport type VerifyBrowserWidgetContextInput = {\n hostOrigin: string;\n bootstrapTicket?: string | null;\n installationId?: string | null;\n bindToolName?: string | null;\n toolName?: string | null;\n subjectId?: string | null;\n};\n\nexport type WidgetBootstrapOriginPolicyInput = {\n hostOrigin: string | null | undefined;\n allowedOrigins?: string[] | string | null | undefined;\n};\n\nexport type WidgetBootstrapOriginPolicyResult =\n | {\n ok: true;\n hostOrigin: string;\n allowedOrigins: string[];\n }\n | {\n ok: false;\n code: \"HOST_ORIGIN_REQUIRED\" | \"HOST_ORIGIN_NOT_ALLOWED\";\n message: string;\n hostOrigin: string | null;\n allowedOrigins: string[];\n };\n\nfunction normalizeOrigin(value: string | null | undefined) {\n const raw = String(value || \"\").trim();\n if (!raw) return null;\n try {\n const parsed = new URL(raw);\n if (!parsed.protocol || !parsed.host) return null;\n return parsed.origin;\n } catch {\n return null;\n }\n}\n\nexport function normalizeWidgetBootstrapAllowedOrigins(\n value: string[] | string | null | undefined,\n): string[] {\n const entries = Array.isArray(value) ? value : String(value || \"\").split(/[,\\n]/);\n const normalized = entries\n .map((entry) => normalizeOrigin(entry))\n .filter((entry): entry is string => Boolean(entry));\n return Array.from(new Set(normalized));\n}\n\nexport function evaluateWidgetBootstrapOriginPolicy(\n input: WidgetBootstrapOriginPolicyInput,\n): WidgetBootstrapOriginPolicyResult {\n const hostOrigin = normalizeOrigin(input.hostOrigin);\n const allowedOrigins = normalizeWidgetBootstrapAllowedOrigins(input.allowedOrigins);\n if (!hostOrigin) {\n return {\n ok: false,\n code: \"HOST_ORIGIN_REQUIRED\",\n message: \"Host origin is required to verify browser widget context\",\n hostOrigin: null,\n allowedOrigins,\n };\n }\n if (allowedOrigins.length > 0 && !allowedOrigins.includes(hostOrigin)) {\n return {\n ok: false,\n code: \"HOST_ORIGIN_NOT_ALLOWED\",\n message: \"Host origin is not allowed for widget bootstrap verification\",\n hostOrigin,\n allowedOrigins,\n };\n }\n return {\n ok: true,\n hostOrigin,\n allowedOrigins,\n };\n}\n\nexport async function verifyBrowserWidgetContext(\n gatewayClient: {\n verifyBrowserWidgetContext: (\n input: VerifyBrowserWidgetContextInput,\n ) => Promise<Record<string, unknown>>;\n },\n input: VerifyBrowserWidgetContextInput,\n) {\n return gatewayClient.verifyBrowserWidgetContext(input);\n}\n\nexport async function createBackendKit(\n input: StringRecord = {},\n deps: BackendKitDeps = {},\n): Promise<BackendKit> {\n const normalizeOptions =\n typeof deps.normalizeOptions === \"function\" ? deps.normalizeOptions : null;\n const createReferenceSurfaceModuleDep =\n typeof deps.createReferenceSurfaceModule === \"function\"\n ? deps.createReferenceSurfaceModule\n : null;\n const createHostReferenceModuleDep =\n typeof deps.createHostReferenceModule === \"function\" ? deps.createHostReferenceModule : null;\n const createGatewayExecutionModuleDep =\n typeof deps.createGatewayExecutionModule === \"function\"\n ? deps.createGatewayExecutionModule\n : null;\n if (\n !normalizeOptions ||\n !createReferenceSurfaceModuleDep ||\n !createHostReferenceModuleDep ||\n !createGatewayExecutionModuleDep\n ) {\n throw new TypeError(\"backend kit dependencies are incomplete\");\n }\n\n const options = normalizeOptions(input);\n const paymentRuntime = await createPaymentRuntime(options, deps);\n\n const referenceSurfaceModule = createReferenceSurfaceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n enableReference: options.host.enableReference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n enabledModes: options.payments.enabledModes,\n reference: options.reference,\n });\n const hostReferenceModule = createHostReferenceModuleDep({\n gateway: options.gateway,\n branding: options.branding,\n reference: options.reference,\n enableLifecycle: options.host.enableLifecycle,\n enableBridge: options.host.enableBridge,\n allowedOrigins: options.host.allowedOrigins,\n bootstrap: options.host.bootstrap,\n hostProxyService: options.overrides.hostProxyService,\n });\n const gatewayExecutionModule = createGatewayExecutionModuleDep({\n enabledModes: options.payments.enabledModes,\n subjectProfiles: options.subjectProfiles,\n paymentRuntime,\n });\n\n return {\n options,\n async registerRoutes(app) {\n await referenceSurfaceModule.registerRoutes(app);\n await hostReferenceModule.registerRoutes(app);\n await gatewayExecutionModule.registerRoutes(app);\n },\n applyNotFoundHandler(app) {\n app.setNotFoundHandler(async (_request, reply) =>\n reply.code(404).send({ message: \"Not found\" }),\n );\n },\n };\n}\n\nexport {\n buildHostedGatewayPaymentUrl as buildHostedGatewayPaymentUrl,\n buildModeHostedGatewayPaymentUrl as buildModeHostedGatewayPaymentUrl,\n createGatewayExecutionModule,\n createHostReferenceModule,\n createReferenceSurfaceModule,\n createHostProxyService,\n createPaymentEvidenceHandler,\n createPaymentRuntime,\n extractHostedPaymentSessionId,\n normalizeBackendKitOptions,\n registerPaymentPageApiRoutes,\n registerPaymentPageAssetRoute,\n resolvePlatformSecretRefFromEnv,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xapps-platform/backend-kit",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "author": "Daniel Vladescu <daniel.vladescu@gmail.com>",
6
6
  "description": "Modular Node backend kit for the current Xapps backend contract (tenant surface today, shared actor-adapter direction later)",
@@ -37,6 +37,6 @@
37
37
  "smoke": "npm run build && node examples/smoke/smoke.mjs"
38
38
  },
39
39
  "dependencies": {
40
- "@xapps-platform/server-sdk": "^0.1.0"
40
+ "@xapps-platform/server-sdk": "^0.2.0"
41
41
  }
42
42
  }