@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 +62 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -1
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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.
|
|
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.
|
|
40
|
+
"@xapps-platform/server-sdk": "^0.2.0"
|
|
41
41
|
}
|
|
42
42
|
}
|