@base44-preview/sdk 0.8.53-pr.322.e2bf534 → 0.8.53-pr.323.0c3777e

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.
@@ -5,8 +5,9 @@ export interface AiGatewayConnection {
5
5
  /** Base URL of the selected gateway provider. */
6
6
  baseURL: string;
7
7
  /**
8
- * Bearer token that authenticates the request. Empty string when the caller is
9
- * unauthenticated.
8
+ * Bearer token that authenticates the request: the service-role token from
9
+ * `base44.asServiceRole.aiGateway`, or the signed-in user's token from
10
+ * `base44.aiGateway`. The gateway expects the service-role token.
10
11
  */
11
12
  token: string;
12
13
  /**
@@ -91,8 +92,8 @@ export interface AiGatewayModuleConfig {
91
92
  *
92
93
  * The mode determines which token `connection()` returns:
93
94
  *
94
- * - **User authentication** (`base44.aiGateway`): Returns the signed-in app user's token.
95
- * - **Service role authentication** (`base44.asServiceRole.aiGateway`): Returns the service-role token instead. Use it from backend functions: apps that restrict Core integrations, the default for new apps, reject user-token gateway calls on public apps. It also works when there's no signed-in user, such as from a scheduled automation.
95
+ * - **Service role authentication** (`base44.asServiceRole.aiGateway`): Returns the app's service-role token. Use it server-side; the gateway rejects other calls with a `403` and the error code `ai_gateway_requires_service_role`. It also works with no signed-in user, such as from a scheduled automation.
96
+ * - **User authentication** (`base44.aiGateway`): Returns the signed-in app user's token. The gateway accepts it only on apps shared privately or with your workspace.
96
97
  *
97
98
  * ## Billing and limits
98
99
  *
@@ -19,7 +19,7 @@ export type IntegrationEndpointFunction = (data: Record<string, any>) => Promise
19
19
  * ```typescript
20
20
  * await base44.integrations.Core.InvokeLLM({
21
21
  * prompt: 'Explain quantum computing',
22
- * model: 'gpt_5'
22
+ * model: 'gemini_3_8_flash'
23
23
  * });
24
24
  * ```
25
25
  *
@@ -43,9 +43,9 @@ export interface InvokeLLMParams {
43
43
  prompt: string;
44
44
  /** Optionally specify a model to override the app-level model setting for this specific call.
45
45
  *
46
- * Options: `"gpt_5_mini"`, `"gemini_3_flash"`, `"gpt_5_4"`, `"gpt_5_6_sol"`, `"gpt_5_6_luna"`, `"gemini_3_1_pro"`, `"claude_sonnet_4_6"`, `"claude_opus_4_6"`, `"claude_opus_4_7"`, `"claude_opus_4_8"`, `"claude-sonnet-5"`
46
+ * Options: `"gemini_3_8_flash"`, `"gpt_6_luna"`, `"claude-sonnet-5"`, `"claude_opus_5_5"`, `"gpt_6_sol"`, `"gpt_6_astra"`, `"claude_fable_5_1"`, `"glm_5_2"`, `"gemini_3_1_pro"`, `"gpt_5_4"`, `"claude_sonnet_4_6"`, `"claude_opus_4_6"`, `"claude_opus_4_7"`, `"claude_opus_4_8"`, `"claude_opus_5"`, `"gpt_5_6_terra"`, `"gpt_5_6_sol"`, `"gpt_5_6_luna"`
47
47
  */
48
- model?: 'gpt_5_mini' | 'gemini_3_flash' | 'gpt_5_4' | 'gpt_5_6_sol' | 'gpt_5_6_luna' | 'gemini_3_1_pro' | 'claude_sonnet_4_6' | 'claude_opus_4_6' | 'claude_opus_4_7' | 'claude_opus_4_8' | 'claude-sonnet-5';
48
+ model?: 'gemini_3_8_flash' | 'gpt_6_luna' | 'claude-sonnet-5' | 'claude_opus_5_5' | 'gpt_6_sol' | 'gpt_6_astra' | 'claude_fable_5_1' | 'glm_5_2' | 'gemini_3_1_pro' | 'gpt_5_4' | 'claude_sonnet_4_6' | 'claude_opus_4_6' | 'claude_opus_4_7' | 'claude_opus_4_8' | 'claude_opus_5' | 'gpt_5_6_terra' | 'gpt_5_6_sol' | 'gpt_5_6_luna';
49
49
  /** If set to `true`, the LLM will use Google Search, Maps, and News to gather real-time context before answering.
50
50
  * @default false
51
51
  */
@@ -1,9 +1,22 @@
1
1
  import type { CheckoutElement, CheckoutMount, CompleteCheckoutResult, MountableCheckout, MountCheckoutOptions } from "./payments.types.js";
2
2
  /** @internal */
3
3
  export type LoadScript = (src: string) => Promise<void>;
4
+ /**
5
+ * The response of `GET /payments/config`.
6
+ * @internal
7
+ */
8
+ export interface PaymentsCheckoutConfig {
9
+ paypal?: {
10
+ script_url?: string;
11
+ };
12
+ stripe?: {
13
+ script_url?: string;
14
+ };
15
+ }
4
16
  /** @internal */
5
17
  export interface MountCheckoutDeps {
6
18
  completeCheckout: (checkoutId: string) => Promise<CompleteCheckoutResult>;
19
+ getConfig: () => Promise<PaymentsCheckoutConfig>;
7
20
  loadScript: LoadScript;
8
21
  }
9
22
  /**
@@ -1,11 +1,29 @@
1
- // PayPal JS SDK v6: https://developer.paypal.com/sdk/js/reference
2
- const PAYPAL_SCRIPT_URLS = {
3
- live: "https://www.paypal.com/web-sdk/v6/core",
4
- sandbox: "https://www.sandbox.paypal.com/web-sdk/v6/core",
1
+ // The backend picks each script URL, but the script runs on the buyer's page, so only these hosts may load.
2
+ const ALLOWED_SCRIPT_HOSTS = {
3
+ paypal: ["www.paypal.com", "www.sandbox.paypal.com"],
4
+ stripe: ["js.stripe.com"],
5
5
  };
6
- // Use v3 rather than a dated release, because Base44 creates sessions with ui_mode "embedded",
7
- // which dahlia and later reject.
8
- const STRIPE_SCRIPT_URL = "https://js.stripe.com/v3/";
6
+ async function scriptUrlFor(provider, deps) {
7
+ var _a, _b;
8
+ const value = (_b = (_a = (await deps.getConfig())) === null || _a === void 0 ? void 0 : _a[provider]) === null || _b === void 0 ? void 0 : _b.script_url;
9
+ let url;
10
+ try {
11
+ url = value ? new URL(value) : undefined;
12
+ }
13
+ catch (_c) {
14
+ url = undefined;
15
+ }
16
+ if (!url ||
17
+ url.protocol !== "https:" ||
18
+ url.port !== "" ||
19
+ url.username !== "" ||
20
+ url.password !== "" ||
21
+ !ALLOWED_SCRIPT_HOSTS[provider].includes(url.hostname)) {
22
+ const name = provider === "paypal" ? "PayPal" : "Stripe";
23
+ throw new Error(`The payments config has no valid ${name} script URL`);
24
+ }
25
+ return url.href;
26
+ }
9
27
  function browserGlobals() {
10
28
  return window;
11
29
  }
@@ -49,10 +67,10 @@ const stripeInstances = new Map();
49
67
  // Stripe allows one Embedded Checkout at a time, so mounts run in order and replace the last.
50
68
  let stripeQueue = Promise.resolve();
51
69
  let activeStripeCheckout = null;
52
- function mountStripe(element, embedded, deps) {
70
+ function mountStripe(element, scriptUrl, embedded, deps) {
53
71
  const mount = stripeQueue.then(async () => {
54
72
  var _a;
55
- const Stripe = await loadGlobal(STRIPE_SCRIPT_URL, () => browserGlobals().Stripe, deps.loadScript);
73
+ const Stripe = await loadGlobal(scriptUrl, () => browserGlobals().Stripe, deps.loadScript);
56
74
  let stripe = stripeInstances.get(embedded.publishable_key);
57
75
  if (!stripe) {
58
76
  stripe = Stripe(embedded.publishable_key);
@@ -92,31 +110,9 @@ function mountStripe(element, embedded, deps) {
92
110
  stripeQueue = mount.catch(() => undefined);
93
111
  return mount;
94
112
  }
95
- // The v6 script for one environment defines the same global as the other's.
96
- let loadedPayPalEnvironment;
97
- async function mountPayPal(element, checkoutId, currency, embedded, options, deps) {
113
+ async function mountPayPal(element, scriptUrl, checkoutId, currency, embedded, options, deps) {
98
114
  var _a;
99
- const environment = embedded.environment;
100
- const scriptUrl = PAYPAL_SCRIPT_URLS[environment];
101
- if (!scriptUrl) {
102
- throw new Error("This checkout is missing embedded.environment. Pass the full result of createCheckout() to mountCheckout().");
103
- }
104
- if (loadedPayPalEnvironment && loadedPayPalEnvironment !== environment) {
105
- throw new Error(`PayPal's ${loadedPayPalEnvironment} script is already loaded on this page, so a ${environment} checkout can't mount. Reload the page first.`);
106
- }
107
- // The environment of a PayPal script the app loaded itself can't be detected, so it's trusted.
108
- if (!browserGlobals().paypal && !loadedPayPalEnvironment) {
109
- loadedPayPalEnvironment = environment;
110
- }
111
- let paypal;
112
- try {
113
- paypal = await loadGlobal(scriptUrl, () => browserGlobals().paypal, deps.loadScript);
114
- }
115
- catch (error) {
116
- if (!browserGlobals().paypal)
117
- loadedPayPalEnvironment = undefined;
118
- throw error;
119
- }
115
+ const paypal = await loadGlobal(scriptUrl, () => browserGlobals().paypal, deps.loadScript);
120
116
  if (typeof paypal.createInstance !== "function") {
121
117
  throw new Error("Another PayPal JS SDK version is already loaded on this page. Remove it to use mountCheckout().");
122
118
  }
@@ -230,9 +226,9 @@ export async function mountCheckout(element, checkout, options, deps) {
230
226
  }
231
227
  switch (embedded.provider) {
232
228
  case "stripe":
233
- return mountStripe(element, embedded, deps);
229
+ return mountStripe(element, await scriptUrlFor("stripe", deps), embedded, deps);
234
230
  case "paypal":
235
- return mountPayPal(element, checkout.checkout_id, checkout.currency, embedded, options, deps);
231
+ return mountPayPal(element, await scriptUrlFor("paypal", deps), checkout.checkout_id, checkout.currency, embedded, options, deps);
236
232
  default:
237
233
  throw new Error(`Embedded checkout isn't supported for provider ${embedded.provider}`);
238
234
  }
@@ -1,4 +1,4 @@
1
- import { loadScript, mountCheckout } from "./payments-checkout.js";
1
+ import { loadScript, mountCheckout, } from "./payments-checkout.js";
2
2
  function requireId(value, name) {
3
3
  if (!value || typeof value !== "string") {
4
4
  throw new Error(`${name} is required and must be a string`);
@@ -45,12 +45,22 @@ function createPaymentsRequests(axios, appId) {
45
45
  */
46
46
  export function createPaymentsModule(axios, appId) {
47
47
  const requests = createPaymentsRequests(axios, appId);
48
+ // One fetch per client, retried on the next mount if it fails.
49
+ let config;
50
+ const getConfig = () => {
51
+ config !== null && config !== void 0 ? config : (config = axios.get(`/apps/${appId}/payments/config`).catch((error) => {
52
+ config = undefined;
53
+ throw error;
54
+ }));
55
+ return config;
56
+ };
48
57
  return {
49
58
  completeCheckout: requests.completeCheckout,
50
59
  listPurchases: requests.listPurchases,
51
60
  mountCheckout(element, checkout, options = {}) {
52
61
  return mountCheckout(element, checkout, options, {
53
62
  completeCheckout: requests.completeCheckout,
63
+ getConfig,
54
64
  loadScript,
55
65
  });
56
66
  },
@@ -111,8 +111,6 @@ export interface PayPalEmbeddedCheckout {
111
111
  partner_attribution_id?: string | null;
112
112
  /** Whether the checkout is a one-time payment or a subscription. */
113
113
  intent: "capture" | "subscription";
114
- /** PayPal environment the checkout was created in. */
115
- environment: "sandbox" | "live";
116
114
  }
117
115
  /**
118
116
  * Data that an embedded checkout needs to render, by provider.
@@ -258,7 +256,7 @@ export interface SubscriptionResult {
258
256
  /** ID of the subscription. */
259
257
  subscription_id: string;
260
258
  /** Current status of the subscription. */
261
- status: "active" | "paused" | "canceled";
259
+ status: "active" | "past_due" | "paused" | "canceled";
262
260
  /** Whether the subscription is set to cancel at the end of the current billing period. */
263
261
  cancel_at_period_end: boolean;
264
262
  }
@@ -282,7 +280,9 @@ export interface MountCheckoutOptions {
282
280
  /**
283
281
  * Called after the buyer approves a PayPal payment and the SDK completes the checkout.
284
282
  *
285
- * Stripe doesn't call this. After a Stripe payment, the buyer returns to the checkout's `success_path` with a `session_id` query parameter. That parameter is the `checkout_id`. Check the purchase there with [`listPurchases()`](/developers/references/sdk/docs/interfaces/payments#listpurchases).
283
+ * Use it to update the page, not to grant access. Browser callbacks can be faked, so unlock paid content only after your backend confirms the purchase, for example with [`listPurchases()`](/developers/references/sdk/docs/interfaces/service-role-payments#listpurchases) in a backend function.
284
+ *
285
+ * Stripe doesn't call this. After a Stripe payment, the buyer returns to the checkout's `success_path` with a `session_id` query parameter. That parameter is the `checkout_id`. Show the result there with [`listPurchases()`](/developers/references/sdk/docs/interfaces/payments#listpurchases), and grant access only after your backend confirms it.
286
286
  */
287
287
  onComplete?: (result: CompleteCheckoutResult) => void;
288
288
  /** Called when the buyer closes the PayPal window without paying. The button stays mounted so the buyer can try again. */
@@ -405,7 +405,9 @@ export interface PaymentsModule {
405
405
  * - PayPal: Renders a PayPal button. When the buyer approves the payment, the SDK calls {@linkcode completeCheckout | completeCheckout()} and then `onComplete`.
406
406
  * - Stripe: Mounts Stripe Embedded Checkout. After paying, the buyer returns to the checkout's `success_path`. Stripe allows one embedded checkout per page, so mounting another Stripe checkout destroys the previous one.
407
407
  *
408
- * Requires a browser environment and can't be used in the backend. Rejects when the checkout isn't embedded, when the provider's script fails to load, or when PayPal isn't available for the checkout's currency.
408
+ * Requires a browser environment and can't be used in the backend. Rejects when the checkout isn't embedded, when the payments config can't be fetched or has no valid script URL for the provider, when the provider's script fails to load, or when PayPal isn't available for the checkout's currency.
409
+ *
410
+ * The checkout's callbacks run in the buyer's browser, where they can be faked. Grant access to what the buyer paid for only after your backend confirms the purchase, for example with [`listPurchases()`](/developers/references/sdk/docs/interfaces/service-role-payments#listpurchases) in a backend function.
409
411
  *
410
412
  * @param element - Element to render the checkout in. It should be empty.
411
413
  * @param checkout - The result of [`createCheckout()`](/developers/references/sdk/docs/interfaces/service-role-payments#createcheckout).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/sdk",
3
- "version": "0.8.53-pr.322.e2bf534",
3
+ "version": "0.8.53-pr.323.0c3777e",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",