@scalemule/nextjs 0.0.11 → 0.0.13

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.d.mts CHANGED
@@ -26,6 +26,8 @@ interface ScaleMuleContextValue {
26
26
  publishableKey?: string;
27
27
  /** Gateway URL for direct API calls */
28
28
  gatewayUrl?: string;
29
+ /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
30
+ bootstrapFlags?: Record<string, unknown>;
29
31
  }
30
32
  interface ScaleMuleProviderProps extends ScaleMuleConfig {
31
33
  children: ReactNode;
@@ -35,8 +37,10 @@ interface ScaleMuleProviderProps extends ScaleMuleConfig {
35
37
  onLogout?: () => void;
36
38
  /** Called on authentication error */
37
39
  onAuthError?: (error: ApiError) => void;
40
+ /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
41
+ bootstrapFlags?: Record<string, unknown>;
38
42
  }
39
- declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, children, onLogin, onLogout, onAuthError, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
43
+ declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, children, onLogin, onLogout, onAuthError, bootstrapFlags, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
40
44
  declare function useScaleMule(): ScaleMuleContextValue;
41
45
  declare function useScaleMuleClient(): ScaleMuleClient;
42
46
 
package/dist/index.d.ts CHANGED
@@ -26,6 +26,8 @@ interface ScaleMuleContextValue {
26
26
  publishableKey?: string;
27
27
  /** Gateway URL for direct API calls */
28
28
  gatewayUrl?: string;
29
+ /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
30
+ bootstrapFlags?: Record<string, unknown>;
29
31
  }
30
32
  interface ScaleMuleProviderProps extends ScaleMuleConfig {
31
33
  children: ReactNode;
@@ -35,8 +37,10 @@ interface ScaleMuleProviderProps extends ScaleMuleConfig {
35
37
  onLogout?: () => void;
36
38
  /** Called on authentication error */
37
39
  onAuthError?: (error: ApiError) => void;
40
+ /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
41
+ bootstrapFlags?: Record<string, unknown>;
38
42
  }
39
- declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, children, onLogin, onLogout, onAuthError, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
43
+ declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, children, onLogin, onLogout, onAuthError, bootstrapFlags, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
40
44
  declare function useScaleMule(): ScaleMuleContextValue;
41
45
  declare function useScaleMuleClient(): ScaleMuleClient;
42
46
 
package/dist/index.js CHANGED
@@ -817,7 +817,8 @@ function ScaleMuleProvider({
817
817
  children,
818
818
  onLogin,
819
819
  onLogout,
820
- onAuthError
820
+ onAuthError,
821
+ bootstrapFlags
821
822
  }) {
822
823
  const [user, setUser] = react.useState(null);
823
824
  const [initializing, setInitializing] = react.useState(true);
@@ -929,9 +930,10 @@ function ScaleMuleProvider({
929
930
  analyticsProxyUrl,
930
931
  authProxyUrl,
931
932
  publishableKey,
932
- gatewayUrl: gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com")
933
+ gatewayUrl: gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com"),
934
+ bootstrapFlags
933
935
  }),
934
- [client, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, gatewayUrl, environment]
936
+ [client, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, gatewayUrl, environment, bootstrapFlags]
935
937
  );
936
938
  return /* @__PURE__ */ jsxRuntime.jsx(ScaleMuleContext.Provider, { value, children });
937
939
  }
@@ -2851,9 +2853,20 @@ function useFeatureFlags(options = {}) {
2851
2853
  keys,
2852
2854
  enabled = true
2853
2855
  } = options;
2854
- const { client, publishableKey, gatewayUrl } = useScaleMule();
2855
- const [flags, setFlags] = react.useState({});
2856
- const [loading, setLoading] = react.useState(enabled);
2856
+ const { client, publishableKey, gatewayUrl, bootstrapFlags } = useScaleMule();
2857
+ const initialFlags = react.useMemo(() => {
2858
+ if (!bootstrapFlags) return {};
2859
+ const result = {};
2860
+ for (const [key, value] of Object.entries(bootstrapFlags)) {
2861
+ if (value && typeof value === "object" && "flag_key" in value) {
2862
+ result[key] = value;
2863
+ }
2864
+ }
2865
+ return result;
2866
+ }, [bootstrapFlags]);
2867
+ const hasBootstrap = Object.keys(initialFlags).length > 0;
2868
+ const [flags, setFlags] = react.useState(initialFlags);
2869
+ const [loading, setLoading] = react.useState(enabled && !hasBootstrap);
2857
2870
  const [error, setError] = react.useState(null);
2858
2871
  const contextRef = react.useRef(context);
2859
2872
  const keysKey = react.useMemo(() => keys && keys.length > 0 ? [...keys].sort().join("|") : "", [keys]);
@@ -2895,9 +2908,15 @@ function useFeatureFlags(options = {}) {
2895
2908
  setLoading(false);
2896
2909
  }
2897
2910
  }, [client, enabled, environment, keys, keysKey, publishableKey, gatewayUrl]);
2911
+ const bootstrapCoversKeys = react.useMemo(() => {
2912
+ if (!hasBootstrap || !keys || keys.length === 0) return false;
2913
+ return keys.every((k) => k in initialFlags);
2914
+ }, [hasBootstrap, keys, initialFlags]);
2898
2915
  react.useEffect(() => {
2899
- void refresh();
2900
- }, [refresh]);
2916
+ if (!bootstrapCoversKeys) {
2917
+ void refresh();
2918
+ }
2919
+ }, [refresh, bootstrapCoversKeys]);
2901
2920
  const isEnabled = react.useCallback(
2902
2921
  (flagKey, fallback = false) => {
2903
2922
  const evaluation = flags[flagKey];
package/dist/index.mjs CHANGED
@@ -815,7 +815,8 @@ function ScaleMuleProvider({
815
815
  children,
816
816
  onLogin,
817
817
  onLogout,
818
- onAuthError
818
+ onAuthError,
819
+ bootstrapFlags
819
820
  }) {
820
821
  const [user, setUser] = useState(null);
821
822
  const [initializing, setInitializing] = useState(true);
@@ -927,9 +928,10 @@ function ScaleMuleProvider({
927
928
  analyticsProxyUrl,
928
929
  authProxyUrl,
929
930
  publishableKey,
930
- gatewayUrl: gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com")
931
+ gatewayUrl: gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com"),
932
+ bootstrapFlags
931
933
  }),
932
- [client, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, gatewayUrl, environment]
934
+ [client, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, gatewayUrl, environment, bootstrapFlags]
933
935
  );
934
936
  return /* @__PURE__ */ jsx(ScaleMuleContext.Provider, { value, children });
935
937
  }
@@ -2849,9 +2851,20 @@ function useFeatureFlags(options = {}) {
2849
2851
  keys,
2850
2852
  enabled = true
2851
2853
  } = options;
2852
- const { client, publishableKey, gatewayUrl } = useScaleMule();
2853
- const [flags, setFlags] = useState({});
2854
- const [loading, setLoading] = useState(enabled);
2854
+ const { client, publishableKey, gatewayUrl, bootstrapFlags } = useScaleMule();
2855
+ const initialFlags = useMemo(() => {
2856
+ if (!bootstrapFlags) return {};
2857
+ const result = {};
2858
+ for (const [key, value] of Object.entries(bootstrapFlags)) {
2859
+ if (value && typeof value === "object" && "flag_key" in value) {
2860
+ result[key] = value;
2861
+ }
2862
+ }
2863
+ return result;
2864
+ }, [bootstrapFlags]);
2865
+ const hasBootstrap = Object.keys(initialFlags).length > 0;
2866
+ const [flags, setFlags] = useState(initialFlags);
2867
+ const [loading, setLoading] = useState(enabled && !hasBootstrap);
2855
2868
  const [error, setError] = useState(null);
2856
2869
  const contextRef = useRef(context);
2857
2870
  const keysKey = useMemo(() => keys && keys.length > 0 ? [...keys].sort().join("|") : "", [keys]);
@@ -2893,9 +2906,15 @@ function useFeatureFlags(options = {}) {
2893
2906
  setLoading(false);
2894
2907
  }
2895
2908
  }, [client, enabled, environment, keys, keysKey, publishableKey, gatewayUrl]);
2909
+ const bootstrapCoversKeys = useMemo(() => {
2910
+ if (!hasBootstrap || !keys || keys.length === 0) return false;
2911
+ return keys.every((k) => k in initialFlags);
2912
+ }, [hasBootstrap, keys, initialFlags]);
2896
2913
  useEffect(() => {
2897
- void refresh();
2898
- }, [refresh]);
2914
+ if (!bootstrapCoversKeys) {
2915
+ void refresh();
2916
+ }
2917
+ }, [refresh, bootstrapCoversKeys]);
2899
2918
  const isEnabled = useCallback(
2900
2919
  (flagKey, fallback = false) => {
2901
2920
  const evaluation = flags[flagKey];
@@ -433,6 +433,52 @@ declare function apiHandler(handler: HandlerFn, options?: HandlerOptions): (requ
433
433
  params: Promise<Record<string, string | string[]>>;
434
434
  }) => Promise<Response>;
435
435
 
436
+ /**
437
+ * Server-side flag bootstrapping for Next.js layouts.
438
+ *
439
+ * Evaluates feature flags on the server during SSR so the client
440
+ * has correct values on first render -- no loading flash, no race condition.
441
+ *
442
+ * Results are cached in-memory with a configurable TTL (default: 60s) to
443
+ * prevent excessive API calls. Since feature flags change infrequently,
444
+ * a short cache window is fine and avoids hammering the flags service on
445
+ * every page render.
446
+ *
447
+ * @example
448
+ * ```ts
449
+ * // app/layout.tsx
450
+ * import { getBootstrapFlags } from '@scalemule/nextjs/server'
451
+ *
452
+ * export default async function RootLayout({ children }) {
453
+ * const bootstrapFlags = await getBootstrapFlags(['analytics.tracking_enabled'])
454
+ * return (
455
+ * <Providers bootstrapFlags={bootstrapFlags}>
456
+ * {children}
457
+ * </Providers>
458
+ * )
459
+ * }
460
+ * ```
461
+ */
462
+ /**
463
+ * Evaluate feature flags server-side for bootstrapping the client provider.
464
+ *
465
+ * Extracts the client IP from request headers (x-forwarded-for, x-real-ip)
466
+ * and passes it as ip_address in the evaluation context so IP-based targeting
467
+ * rules work correctly.
468
+ *
469
+ * Results are cached in-memory for `cacheTtlMs` milliseconds (default: 60s).
470
+ * Pass `cacheTtlMs: 0` to disable caching.
471
+ *
472
+ * Returns a Record that can be passed directly to ScaleMuleProvider's
473
+ * bootstrapFlags prop.
474
+ *
475
+ * @param flagKeys - Array of flag keys to evaluate
476
+ * @param environment - Environment name (default: 'prod')
477
+ * @param extraContext - Additional context attributes to include
478
+ * @param cacheTtlMs - Cache TTL in milliseconds (default: 60000). Set to 0 to disable.
479
+ */
480
+ declare function getBootstrapFlags(flagKeys: string[], environment?: string, extraContext?: Record<string, unknown>, cacheTtlMs?: number): Promise<Record<string, unknown>>;
481
+
436
482
  /**
437
483
  * Next.js Middleware Helpers
438
484
  *
@@ -868,4 +914,4 @@ declare function invalidateBundleCache(key?: string): void;
868
914
  */
869
915
  declare function prefetchBundles(keys: string[]): Promise<void>;
870
916
 
871
- export { type AnalyticsRoutesConfig, type AuthMiddlewareConfig, type AuthRoutesConfig, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type HandlerContext, type HandlerOptions, type MySqlBundle, OAUTH_STATE_COOKIE_NAME, type OAuthBundle, type PostgresBundle, type RedisBundle, type S3Bundle, SESSION_COOKIE_NAME, ScaleMuleError, ServerConfig, type SessionCookieOptions, type SessionData, type SmtpBundle, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, prefetchBundles, prefetchSecrets, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, withAuth, withCSRFProtection, withCSRFToken, withSession };
917
+ export { type AnalyticsRoutesConfig, type AuthMiddlewareConfig, type AuthRoutesConfig, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type HandlerContext, type HandlerOptions, type MySqlBundle, OAUTH_STATE_COOKIE_NAME, type OAuthBundle, type PostgresBundle, type RedisBundle, type S3Bundle, SESSION_COOKIE_NAME, ScaleMuleError, ServerConfig, type SessionCookieOptions, type SessionData, type SmtpBundle, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBootstrapFlags, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, prefetchBundles, prefetchSecrets, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, withAuth, withCSRFProtection, withCSRFToken, withSession };
@@ -433,6 +433,52 @@ declare function apiHandler(handler: HandlerFn, options?: HandlerOptions): (requ
433
433
  params: Promise<Record<string, string | string[]>>;
434
434
  }) => Promise<Response>;
435
435
 
436
+ /**
437
+ * Server-side flag bootstrapping for Next.js layouts.
438
+ *
439
+ * Evaluates feature flags on the server during SSR so the client
440
+ * has correct values on first render -- no loading flash, no race condition.
441
+ *
442
+ * Results are cached in-memory with a configurable TTL (default: 60s) to
443
+ * prevent excessive API calls. Since feature flags change infrequently,
444
+ * a short cache window is fine and avoids hammering the flags service on
445
+ * every page render.
446
+ *
447
+ * @example
448
+ * ```ts
449
+ * // app/layout.tsx
450
+ * import { getBootstrapFlags } from '@scalemule/nextjs/server'
451
+ *
452
+ * export default async function RootLayout({ children }) {
453
+ * const bootstrapFlags = await getBootstrapFlags(['analytics.tracking_enabled'])
454
+ * return (
455
+ * <Providers bootstrapFlags={bootstrapFlags}>
456
+ * {children}
457
+ * </Providers>
458
+ * )
459
+ * }
460
+ * ```
461
+ */
462
+ /**
463
+ * Evaluate feature flags server-side for bootstrapping the client provider.
464
+ *
465
+ * Extracts the client IP from request headers (x-forwarded-for, x-real-ip)
466
+ * and passes it as ip_address in the evaluation context so IP-based targeting
467
+ * rules work correctly.
468
+ *
469
+ * Results are cached in-memory for `cacheTtlMs` milliseconds (default: 60s).
470
+ * Pass `cacheTtlMs: 0` to disable caching.
471
+ *
472
+ * Returns a Record that can be passed directly to ScaleMuleProvider's
473
+ * bootstrapFlags prop.
474
+ *
475
+ * @param flagKeys - Array of flag keys to evaluate
476
+ * @param environment - Environment name (default: 'prod')
477
+ * @param extraContext - Additional context attributes to include
478
+ * @param cacheTtlMs - Cache TTL in milliseconds (default: 60000). Set to 0 to disable.
479
+ */
480
+ declare function getBootstrapFlags(flagKeys: string[], environment?: string, extraContext?: Record<string, unknown>, cacheTtlMs?: number): Promise<Record<string, unknown>>;
481
+
436
482
  /**
437
483
  * Next.js Middleware Helpers
438
484
  *
@@ -868,4 +914,4 @@ declare function invalidateBundleCache(key?: string): void;
868
914
  */
869
915
  declare function prefetchBundles(keys: string[]): Promise<void>;
870
916
 
871
- export { type AnalyticsRoutesConfig, type AuthMiddlewareConfig, type AuthRoutesConfig, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type HandlerContext, type HandlerOptions, type MySqlBundle, OAUTH_STATE_COOKIE_NAME, type OAuthBundle, type PostgresBundle, type RedisBundle, type S3Bundle, SESSION_COOKIE_NAME, ScaleMuleError, ServerConfig, type SessionCookieOptions, type SessionData, type SmtpBundle, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, prefetchBundles, prefetchSecrets, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, withAuth, withCSRFProtection, withCSRFToken, withSession };
917
+ export { type AnalyticsRoutesConfig, type AuthMiddlewareConfig, type AuthRoutesConfig, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type HandlerContext, type HandlerOptions, type MySqlBundle, OAUTH_STATE_COOKIE_NAME, type OAuthBundle, type PostgresBundle, type RedisBundle, type S3Bundle, SESSION_COOKIE_NAME, ScaleMuleError, ServerConfig, type SessionCookieOptions, type SessionData, type SmtpBundle, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBootstrapFlags, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, prefetchBundles, prefetchSecrets, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, withAuth, withCSRFProtection, withCSRFToken, withSession };
@@ -28,40 +28,40 @@ function validateIP(ip) {
28
28
  return void 0;
29
29
  }
30
30
  function extractClientContext(request) {
31
- const headers = request.headers;
31
+ const headers2 = request.headers;
32
32
  let ip;
33
- const cfConnectingIp = headers.get("cf-connecting-ip");
33
+ const cfConnectingIp = headers2.get("cf-connecting-ip");
34
34
  if (cfConnectingIp) {
35
35
  ip = validateIP(cfConnectingIp);
36
36
  }
37
37
  if (!ip) {
38
- const doConnectingIp = headers.get("do-connecting-ip");
38
+ const doConnectingIp = headers2.get("do-connecting-ip");
39
39
  if (doConnectingIp) {
40
40
  ip = validateIP(doConnectingIp);
41
41
  }
42
42
  }
43
43
  if (!ip) {
44
- const realIp = headers.get("x-real-ip");
44
+ const realIp = headers2.get("x-real-ip");
45
45
  if (realIp) {
46
46
  ip = validateIP(realIp);
47
47
  }
48
48
  }
49
49
  if (!ip) {
50
- const forwardedFor = headers.get("x-forwarded-for");
50
+ const forwardedFor = headers2.get("x-forwarded-for");
51
51
  if (forwardedFor) {
52
52
  const firstIp = forwardedFor.split(",")[0]?.trim();
53
53
  ip = validateIP(firstIp);
54
54
  }
55
55
  }
56
56
  if (!ip) {
57
- const vercelForwarded = headers.get("x-vercel-forwarded-for");
57
+ const vercelForwarded = headers2.get("x-vercel-forwarded-for");
58
58
  if (vercelForwarded) {
59
59
  const firstIp = vercelForwarded.split(",")[0]?.trim();
60
60
  ip = validateIP(firstIp);
61
61
  }
62
62
  }
63
63
  if (!ip) {
64
- const trueClientIp = headers.get("true-client-ip");
64
+ const trueClientIp = headers2.get("true-client-ip");
65
65
  if (trueClientIp) {
66
66
  ip = validateIP(trueClientIp);
67
67
  }
@@ -69,9 +69,9 @@ function extractClientContext(request) {
69
69
  if (!ip && request.ip) {
70
70
  ip = validateIP(request.ip);
71
71
  }
72
- const userAgent = headers.get("user-agent") || void 0;
73
- const deviceFingerprint = headers.get("x-device-fingerprint") || void 0;
74
- const referrer = headers.get("referer") || void 0;
72
+ const userAgent = headers2.get("user-agent") || void 0;
73
+ const deviceFingerprint = headers2.get("x-device-fingerprint") || void 0;
74
+ const referrer = headers2.get("referer") || void 0;
75
75
  return {
76
76
  ip,
77
77
  userAgent,
@@ -80,9 +80,9 @@ function extractClientContext(request) {
80
80
  };
81
81
  }
82
82
  function extractClientContextFromReq(req) {
83
- const headers = req.headers;
83
+ const headers2 = req.headers;
84
84
  const getHeader = (name) => {
85
- const value = headers[name.toLowerCase()];
85
+ const value = headers2[name.toLowerCase()];
86
86
  if (Array.isArray(value)) {
87
87
  return value[0];
88
88
  }
@@ -139,24 +139,24 @@ function extractClientContextFromReq(req) {
139
139
  };
140
140
  }
141
141
  function buildClientContextHeaders(context) {
142
- const headers = {};
142
+ const headers2 = {};
143
143
  if (!context) {
144
- return headers;
144
+ return headers2;
145
145
  }
146
146
  if (context.ip) {
147
- headers["x-sm-forwarded-client-ip"] = context.ip;
148
- headers["X-Client-IP"] = context.ip;
147
+ headers2["x-sm-forwarded-client-ip"] = context.ip;
148
+ headers2["X-Client-IP"] = context.ip;
149
149
  }
150
150
  if (context.userAgent) {
151
- headers["X-Client-User-Agent"] = context.userAgent;
151
+ headers2["X-Client-User-Agent"] = context.userAgent;
152
152
  }
153
153
  if (context.deviceFingerprint) {
154
- headers["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
154
+ headers2["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
155
155
  }
156
156
  if (context.referrer) {
157
- headers["X-Client-Referrer"] = context.referrer;
157
+ headers2["X-Client-Referrer"] = context.referrer;
158
158
  }
159
- return headers;
159
+ return headers2;
160
160
  }
161
161
 
162
162
  // src/server/client.ts
@@ -541,7 +541,7 @@ var ScaleMuleServer = class {
541
541
  formData.append("file", blob, file.filename);
542
542
  formData.append("sm_user_id", userId);
543
543
  const url = `${this.gatewayUrl}/v1/storage/upload`;
544
- const headers = {
544
+ const headers2 = {
545
545
  "x-api-key": this.apiKey,
546
546
  "x-user-id": userId,
547
547
  ...buildClientContextHeaders(options?.clientContext)
@@ -552,7 +552,7 @@ var ScaleMuleServer = class {
552
552
  try {
553
553
  const response = await fetch(url, {
554
554
  method: "POST",
555
- headers,
555
+ headers: headers2,
556
556
  body: formData
557
557
  });
558
558
  const text = await response.text();
@@ -763,14 +763,14 @@ var ScaleMuleServer = class {
763
763
  */
764
764
  async request(method, path, options = {}) {
765
765
  const url = `${this.gatewayUrl}${path}`;
766
- const headers = {
766
+ const headers2 = {
767
767
  "x-api-key": this.apiKey,
768
768
  "Content-Type": "application/json",
769
769
  // Forward client context headers if provided
770
770
  ...buildClientContextHeaders(options.clientContext)
771
771
  };
772
772
  if (options.sessionToken) {
773
- headers["Authorization"] = `Bearer ${options.sessionToken}`;
773
+ headers2["Authorization"] = `Bearer ${options.sessionToken}`;
774
774
  }
775
775
  if (this.debug) {
776
776
  console.log(`[ScaleMule Server] ${method} ${path}`);
@@ -781,7 +781,7 @@ var ScaleMuleServer = class {
781
781
  try {
782
782
  const response = await fetch(url, {
783
783
  method,
784
- headers,
784
+ headers: headers2,
785
785
  body: options.body ? JSON.stringify(options.body) : void 0
786
786
  });
787
787
  const text = await response.text();
@@ -852,45 +852,45 @@ function createClearCookieHeader(name, options = {}) {
852
852
  return cookie;
853
853
  }
854
854
  function withSession(loginResponse, responseBody, options = {}) {
855
- const headers = new Headers();
856
- headers.set("Content-Type", "application/json");
857
- headers.append(
855
+ const headers2 = new Headers();
856
+ headers2.set("Content-Type", "application/json");
857
+ headers2.append(
858
858
  "Set-Cookie",
859
859
  createCookieHeader(SESSION_COOKIE_NAME, loginResponse.session_token, options)
860
860
  );
861
- headers.append(
861
+ headers2.append(
862
862
  "Set-Cookie",
863
863
  createCookieHeader(USER_ID_COOKIE_NAME, loginResponse.user.id, options)
864
864
  );
865
865
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
866
866
  status: 200,
867
- headers
867
+ headers: headers2
868
868
  });
869
869
  }
870
870
  function withRefreshedSession(sessionToken, userId, responseBody, options = {}) {
871
- const headers = new Headers();
872
- headers.set("Content-Type", "application/json");
873
- headers.append(
871
+ const headers2 = new Headers();
872
+ headers2.set("Content-Type", "application/json");
873
+ headers2.append(
874
874
  "Set-Cookie",
875
875
  createCookieHeader(SESSION_COOKIE_NAME, sessionToken, options)
876
876
  );
877
- headers.append(
877
+ headers2.append(
878
878
  "Set-Cookie",
879
879
  createCookieHeader(USER_ID_COOKIE_NAME, userId, options)
880
880
  );
881
881
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
882
882
  status: 200,
883
- headers
883
+ headers: headers2
884
884
  });
885
885
  }
886
886
  function clearSession(responseBody, options = {}, status = 200) {
887
- const headers = new Headers();
888
- headers.set("Content-Type", "application/json");
889
- headers.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
890
- headers.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
887
+ const headers2 = new Headers();
888
+ headers2.set("Content-Type", "application/json");
889
+ headers2.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
890
+ headers2.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
891
891
  return new Response(JSON.stringify({ success: status < 300, data: responseBody }), {
892
892
  status,
893
- headers
893
+ headers: headers2
894
894
  });
895
895
  }
896
896
  async function getSession() {
@@ -1765,6 +1765,52 @@ function createWebhookHandler(config = {}) {
1765
1765
  }
1766
1766
  };
1767
1767
  }
1768
+ var _serverClient = null;
1769
+ function getClient() {
1770
+ if (!_serverClient) {
1771
+ _serverClient = createServerClient();
1772
+ }
1773
+ return _serverClient;
1774
+ }
1775
+ var _flagCache = /* @__PURE__ */ new Map();
1776
+ var DEFAULT_CACHE_TTL_MS = 6e4;
1777
+ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext = {}, cacheTtlMs = DEFAULT_CACHE_TTL_MS) {
1778
+ try {
1779
+ const cacheKey = [...flagKeys].sort().join("|") + ":" + environment;
1780
+ if (cacheTtlMs > 0) {
1781
+ const cached = _flagCache.get(cacheKey);
1782
+ if (cached && Date.now() - cached.timestamp < cacheTtlMs) {
1783
+ return cached.result;
1784
+ }
1785
+ }
1786
+ const hdrs = await headers.headers();
1787
+ const forwardedFor = hdrs.get("x-forwarded-for");
1788
+ const realIp = hdrs.get("x-real-ip") || hdrs.get("x-real-client-ip");
1789
+ const clientIp = realIp || (forwardedFor ? forwardedFor.split(",")[0].trim() : void 0);
1790
+ const context = {
1791
+ ...extraContext
1792
+ };
1793
+ if (clientIp) {
1794
+ context.ip_address = clientIp;
1795
+ }
1796
+ const result = await getClient().flags.evaluateBatch(flagKeys, context, environment);
1797
+ const flagResult = result || {};
1798
+ if (cacheTtlMs > 0) {
1799
+ _flagCache.set(cacheKey, { result: flagResult, timestamp: Date.now() });
1800
+ if (_flagCache.size > 100) {
1801
+ const now = Date.now();
1802
+ for (const [key, entry] of _flagCache) {
1803
+ if (now - entry.timestamp > cacheTtlMs) {
1804
+ _flagCache.delete(key);
1805
+ }
1806
+ }
1807
+ }
1808
+ }
1809
+ return flagResult;
1810
+ } catch {
1811
+ return {};
1812
+ }
1813
+ }
1768
1814
  function globToRegex(pattern) {
1769
1815
  const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
1770
1816
  return new RegExp(`^${escaped}$`);
@@ -1892,14 +1938,14 @@ function clearOAuthState(response) {
1892
1938
  }
1893
1939
 
1894
1940
  // src/server/secrets.ts
1895
- var DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
1941
+ var DEFAULT_CACHE_TTL_MS2 = 5 * 60 * 1e3;
1896
1942
  var secretsCache = {};
1897
1943
  var globalConfig = {};
1898
1944
  function configureSecrets(config) {
1899
1945
  globalConfig = { ...globalConfig, ...config };
1900
1946
  }
1901
1947
  async function getAppSecret(key) {
1902
- const cacheTtl = globalConfig.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
1948
+ const cacheTtl = globalConfig.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS2;
1903
1949
  const noCache = globalConfig.noCache ?? false;
1904
1950
  if (!noCache) {
1905
1951
  const cached = secretsCache[key];
@@ -1951,14 +1997,14 @@ async function prefetchSecrets(keys) {
1951
1997
  }
1952
1998
 
1953
1999
  // src/server/bundles.ts
1954
- var DEFAULT_CACHE_TTL_MS2 = 5 * 60 * 1e3;
2000
+ var DEFAULT_CACHE_TTL_MS3 = 5 * 60 * 1e3;
1955
2001
  var bundlesCache = {};
1956
2002
  var globalConfig2 = {};
1957
2003
  function configureBundles(config) {
1958
2004
  globalConfig2 = { ...globalConfig2, ...config };
1959
2005
  }
1960
2006
  async function getBundle(key, resolve = true) {
1961
- const cacheTtl = globalConfig2.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS2;
2007
+ const cacheTtl = globalConfig2.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS3;
1962
2008
  const noCache = globalConfig2.noCache ?? false;
1963
2009
  if (!noCache) {
1964
2010
  const cached = bundlesCache[key];
@@ -2077,6 +2123,7 @@ exports.extractClientContextFromReq = extractClientContextFromReq;
2077
2123
  exports.generateCSRFToken = generateCSRFToken;
2078
2124
  exports.getAppSecret = getAppSecret;
2079
2125
  exports.getAppSecretOrDefault = getAppSecretOrDefault;
2126
+ exports.getBootstrapFlags = getBootstrapFlags;
2080
2127
  exports.getBundle = getBundle;
2081
2128
  exports.getCSRFToken = getCSRFToken;
2082
2129
  exports.getMySqlBundle = getMySqlBundle;
@@ -1,4 +1,4 @@
1
- import { cookies } from 'next/headers';
1
+ import { cookies, headers } from 'next/headers';
2
2
  import { NextResponse } from 'next/server';
3
3
  import { createHmac, timingSafeEqual } from 'crypto';
4
4
 
@@ -26,40 +26,40 @@ function validateIP(ip) {
26
26
  return void 0;
27
27
  }
28
28
  function extractClientContext(request) {
29
- const headers = request.headers;
29
+ const headers2 = request.headers;
30
30
  let ip;
31
- const cfConnectingIp = headers.get("cf-connecting-ip");
31
+ const cfConnectingIp = headers2.get("cf-connecting-ip");
32
32
  if (cfConnectingIp) {
33
33
  ip = validateIP(cfConnectingIp);
34
34
  }
35
35
  if (!ip) {
36
- const doConnectingIp = headers.get("do-connecting-ip");
36
+ const doConnectingIp = headers2.get("do-connecting-ip");
37
37
  if (doConnectingIp) {
38
38
  ip = validateIP(doConnectingIp);
39
39
  }
40
40
  }
41
41
  if (!ip) {
42
- const realIp = headers.get("x-real-ip");
42
+ const realIp = headers2.get("x-real-ip");
43
43
  if (realIp) {
44
44
  ip = validateIP(realIp);
45
45
  }
46
46
  }
47
47
  if (!ip) {
48
- const forwardedFor = headers.get("x-forwarded-for");
48
+ const forwardedFor = headers2.get("x-forwarded-for");
49
49
  if (forwardedFor) {
50
50
  const firstIp = forwardedFor.split(",")[0]?.trim();
51
51
  ip = validateIP(firstIp);
52
52
  }
53
53
  }
54
54
  if (!ip) {
55
- const vercelForwarded = headers.get("x-vercel-forwarded-for");
55
+ const vercelForwarded = headers2.get("x-vercel-forwarded-for");
56
56
  if (vercelForwarded) {
57
57
  const firstIp = vercelForwarded.split(",")[0]?.trim();
58
58
  ip = validateIP(firstIp);
59
59
  }
60
60
  }
61
61
  if (!ip) {
62
- const trueClientIp = headers.get("true-client-ip");
62
+ const trueClientIp = headers2.get("true-client-ip");
63
63
  if (trueClientIp) {
64
64
  ip = validateIP(trueClientIp);
65
65
  }
@@ -67,9 +67,9 @@ function extractClientContext(request) {
67
67
  if (!ip && request.ip) {
68
68
  ip = validateIP(request.ip);
69
69
  }
70
- const userAgent = headers.get("user-agent") || void 0;
71
- const deviceFingerprint = headers.get("x-device-fingerprint") || void 0;
72
- const referrer = headers.get("referer") || void 0;
70
+ const userAgent = headers2.get("user-agent") || void 0;
71
+ const deviceFingerprint = headers2.get("x-device-fingerprint") || void 0;
72
+ const referrer = headers2.get("referer") || void 0;
73
73
  return {
74
74
  ip,
75
75
  userAgent,
@@ -78,9 +78,9 @@ function extractClientContext(request) {
78
78
  };
79
79
  }
80
80
  function extractClientContextFromReq(req) {
81
- const headers = req.headers;
81
+ const headers2 = req.headers;
82
82
  const getHeader = (name) => {
83
- const value = headers[name.toLowerCase()];
83
+ const value = headers2[name.toLowerCase()];
84
84
  if (Array.isArray(value)) {
85
85
  return value[0];
86
86
  }
@@ -137,24 +137,24 @@ function extractClientContextFromReq(req) {
137
137
  };
138
138
  }
139
139
  function buildClientContextHeaders(context) {
140
- const headers = {};
140
+ const headers2 = {};
141
141
  if (!context) {
142
- return headers;
142
+ return headers2;
143
143
  }
144
144
  if (context.ip) {
145
- headers["x-sm-forwarded-client-ip"] = context.ip;
146
- headers["X-Client-IP"] = context.ip;
145
+ headers2["x-sm-forwarded-client-ip"] = context.ip;
146
+ headers2["X-Client-IP"] = context.ip;
147
147
  }
148
148
  if (context.userAgent) {
149
- headers["X-Client-User-Agent"] = context.userAgent;
149
+ headers2["X-Client-User-Agent"] = context.userAgent;
150
150
  }
151
151
  if (context.deviceFingerprint) {
152
- headers["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
152
+ headers2["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
153
153
  }
154
154
  if (context.referrer) {
155
- headers["X-Client-Referrer"] = context.referrer;
155
+ headers2["X-Client-Referrer"] = context.referrer;
156
156
  }
157
- return headers;
157
+ return headers2;
158
158
  }
159
159
 
160
160
  // src/server/client.ts
@@ -539,7 +539,7 @@ var ScaleMuleServer = class {
539
539
  formData.append("file", blob, file.filename);
540
540
  formData.append("sm_user_id", userId);
541
541
  const url = `${this.gatewayUrl}/v1/storage/upload`;
542
- const headers = {
542
+ const headers2 = {
543
543
  "x-api-key": this.apiKey,
544
544
  "x-user-id": userId,
545
545
  ...buildClientContextHeaders(options?.clientContext)
@@ -550,7 +550,7 @@ var ScaleMuleServer = class {
550
550
  try {
551
551
  const response = await fetch(url, {
552
552
  method: "POST",
553
- headers,
553
+ headers: headers2,
554
554
  body: formData
555
555
  });
556
556
  const text = await response.text();
@@ -761,14 +761,14 @@ var ScaleMuleServer = class {
761
761
  */
762
762
  async request(method, path, options = {}) {
763
763
  const url = `${this.gatewayUrl}${path}`;
764
- const headers = {
764
+ const headers2 = {
765
765
  "x-api-key": this.apiKey,
766
766
  "Content-Type": "application/json",
767
767
  // Forward client context headers if provided
768
768
  ...buildClientContextHeaders(options.clientContext)
769
769
  };
770
770
  if (options.sessionToken) {
771
- headers["Authorization"] = `Bearer ${options.sessionToken}`;
771
+ headers2["Authorization"] = `Bearer ${options.sessionToken}`;
772
772
  }
773
773
  if (this.debug) {
774
774
  console.log(`[ScaleMule Server] ${method} ${path}`);
@@ -779,7 +779,7 @@ var ScaleMuleServer = class {
779
779
  try {
780
780
  const response = await fetch(url, {
781
781
  method,
782
- headers,
782
+ headers: headers2,
783
783
  body: options.body ? JSON.stringify(options.body) : void 0
784
784
  });
785
785
  const text = await response.text();
@@ -850,45 +850,45 @@ function createClearCookieHeader(name, options = {}) {
850
850
  return cookie;
851
851
  }
852
852
  function withSession(loginResponse, responseBody, options = {}) {
853
- const headers = new Headers();
854
- headers.set("Content-Type", "application/json");
855
- headers.append(
853
+ const headers2 = new Headers();
854
+ headers2.set("Content-Type", "application/json");
855
+ headers2.append(
856
856
  "Set-Cookie",
857
857
  createCookieHeader(SESSION_COOKIE_NAME, loginResponse.session_token, options)
858
858
  );
859
- headers.append(
859
+ headers2.append(
860
860
  "Set-Cookie",
861
861
  createCookieHeader(USER_ID_COOKIE_NAME, loginResponse.user.id, options)
862
862
  );
863
863
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
864
864
  status: 200,
865
- headers
865
+ headers: headers2
866
866
  });
867
867
  }
868
868
  function withRefreshedSession(sessionToken, userId, responseBody, options = {}) {
869
- const headers = new Headers();
870
- headers.set("Content-Type", "application/json");
871
- headers.append(
869
+ const headers2 = new Headers();
870
+ headers2.set("Content-Type", "application/json");
871
+ headers2.append(
872
872
  "Set-Cookie",
873
873
  createCookieHeader(SESSION_COOKIE_NAME, sessionToken, options)
874
874
  );
875
- headers.append(
875
+ headers2.append(
876
876
  "Set-Cookie",
877
877
  createCookieHeader(USER_ID_COOKIE_NAME, userId, options)
878
878
  );
879
879
  return new Response(JSON.stringify({ success: true, data: responseBody }), {
880
880
  status: 200,
881
- headers
881
+ headers: headers2
882
882
  });
883
883
  }
884
884
  function clearSession(responseBody, options = {}, status = 200) {
885
- const headers = new Headers();
886
- headers.set("Content-Type", "application/json");
887
- headers.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
888
- headers.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
885
+ const headers2 = new Headers();
886
+ headers2.set("Content-Type", "application/json");
887
+ headers2.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
888
+ headers2.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
889
889
  return new Response(JSON.stringify({ success: status < 300, data: responseBody }), {
890
890
  status,
891
- headers
891
+ headers: headers2
892
892
  });
893
893
  }
894
894
  async function getSession() {
@@ -1763,6 +1763,52 @@ function createWebhookHandler(config = {}) {
1763
1763
  }
1764
1764
  };
1765
1765
  }
1766
+ var _serverClient = null;
1767
+ function getClient() {
1768
+ if (!_serverClient) {
1769
+ _serverClient = createServerClient();
1770
+ }
1771
+ return _serverClient;
1772
+ }
1773
+ var _flagCache = /* @__PURE__ */ new Map();
1774
+ var DEFAULT_CACHE_TTL_MS = 6e4;
1775
+ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext = {}, cacheTtlMs = DEFAULT_CACHE_TTL_MS) {
1776
+ try {
1777
+ const cacheKey = [...flagKeys].sort().join("|") + ":" + environment;
1778
+ if (cacheTtlMs > 0) {
1779
+ const cached = _flagCache.get(cacheKey);
1780
+ if (cached && Date.now() - cached.timestamp < cacheTtlMs) {
1781
+ return cached.result;
1782
+ }
1783
+ }
1784
+ const hdrs = await headers();
1785
+ const forwardedFor = hdrs.get("x-forwarded-for");
1786
+ const realIp = hdrs.get("x-real-ip") || hdrs.get("x-real-client-ip");
1787
+ const clientIp = realIp || (forwardedFor ? forwardedFor.split(",")[0].trim() : void 0);
1788
+ const context = {
1789
+ ...extraContext
1790
+ };
1791
+ if (clientIp) {
1792
+ context.ip_address = clientIp;
1793
+ }
1794
+ const result = await getClient().flags.evaluateBatch(flagKeys, context, environment);
1795
+ const flagResult = result || {};
1796
+ if (cacheTtlMs > 0) {
1797
+ _flagCache.set(cacheKey, { result: flagResult, timestamp: Date.now() });
1798
+ if (_flagCache.size > 100) {
1799
+ const now = Date.now();
1800
+ for (const [key, entry] of _flagCache) {
1801
+ if (now - entry.timestamp > cacheTtlMs) {
1802
+ _flagCache.delete(key);
1803
+ }
1804
+ }
1805
+ }
1806
+ }
1807
+ return flagResult;
1808
+ } catch {
1809
+ return {};
1810
+ }
1811
+ }
1766
1812
  function globToRegex(pattern) {
1767
1813
  const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
1768
1814
  return new RegExp(`^${escaped}$`);
@@ -1890,14 +1936,14 @@ function clearOAuthState(response) {
1890
1936
  }
1891
1937
 
1892
1938
  // src/server/secrets.ts
1893
- var DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
1939
+ var DEFAULT_CACHE_TTL_MS2 = 5 * 60 * 1e3;
1894
1940
  var secretsCache = {};
1895
1941
  var globalConfig = {};
1896
1942
  function configureSecrets(config) {
1897
1943
  globalConfig = { ...globalConfig, ...config };
1898
1944
  }
1899
1945
  async function getAppSecret(key) {
1900
- const cacheTtl = globalConfig.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
1946
+ const cacheTtl = globalConfig.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS2;
1901
1947
  const noCache = globalConfig.noCache ?? false;
1902
1948
  if (!noCache) {
1903
1949
  const cached = secretsCache[key];
@@ -1949,14 +1995,14 @@ async function prefetchSecrets(keys) {
1949
1995
  }
1950
1996
 
1951
1997
  // src/server/bundles.ts
1952
- var DEFAULT_CACHE_TTL_MS2 = 5 * 60 * 1e3;
1998
+ var DEFAULT_CACHE_TTL_MS3 = 5 * 60 * 1e3;
1953
1999
  var bundlesCache = {};
1954
2000
  var globalConfig2 = {};
1955
2001
  function configureBundles(config) {
1956
2002
  globalConfig2 = { ...globalConfig2, ...config };
1957
2003
  }
1958
2004
  async function getBundle(key, resolve = true) {
1959
- const cacheTtl = globalConfig2.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS2;
2005
+ const cacheTtl = globalConfig2.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS3;
1960
2006
  const noCache = globalConfig2.noCache ?? false;
1961
2007
  if (!noCache) {
1962
2008
  const cached = bundlesCache[key];
@@ -2050,4 +2096,4 @@ async function prefetchBundles(keys) {
2050
2096
  await Promise.all(keys.map((key) => getBundle(key)));
2051
2097
  }
2052
2098
 
2053
- export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, OAUTH_STATE_COOKIE_NAME, SESSION_COOKIE_NAME, ScaleMuleError, ScaleMuleServer, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, createServerClient, createWebhookHandler, createWebhookRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, parseWebhookEvent, prefetchBundles, prefetchSecrets, registerVideoWebhook, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, verifyWebhookSignature, withAuth, withCSRFProtection, withCSRFToken, withSession };
2099
+ export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, OAUTH_STATE_COOKIE_NAME, SESSION_COOKIE_NAME, ScaleMuleError, ScaleMuleServer, USER_ID_COOKIE_NAME, apiHandler, buildClientContextHeaders, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, createServerClient, createWebhookHandler, createWebhookRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBootstrapFlags, getBundle, getCSRFToken, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, parseWebhookEvent, prefetchBundles, prefetchSecrets, registerVideoWebhook, requireAppSecret, requireBundle, requireSession, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, verifyWebhookSignature, withAuth, withCSRFProtection, withCSRFToken, withSession };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/nextjs",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "ScaleMule SDK for Next.js applications - authentication, storage, and user management",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",