@tern-secure/nextjs 3.1.45 → 3.1.46

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/cjs/index.js CHANGED
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
- };
11
8
  var __export = (target, all) => {
12
9
  for (var name in all)
13
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,51 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
27
  ));
31
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
29
 
33
- // src/boundary/TernSecureCtx.tsx
34
- var import_react, INTERNAL_CONTEXT_KEY, TernSecureContext, useInternalContext;
35
- var init_TernSecureCtx = __esm({
36
- "src/boundary/TernSecureCtx.tsx"() {
37
- "use strict";
38
- "use client";
39
- import_react = require("react");
40
- INTERNAL_CONTEXT_KEY = Symbol("TERN_SECURE_CONTEXT");
41
- TernSecureContext = (0, import_react.createContext)(null);
42
- useInternalContext = (hookName) => {
43
- const context = (0, import_react.useContext)(TernSecureContext);
44
- if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {
45
- throw new Error(
46
- `${hookName || "Hook"} must be used within TernSecureProvider. Please wrap your component with TernSecureProvider.`
47
- );
48
- }
49
- return context;
50
- };
51
- }
52
- });
53
-
54
- // src/app-router/client/TernSecureProvider.tsx
55
- var TernSecureProvider_exports = {};
56
- __export(TernSecureProvider_exports, {
57
- TernSecureClientProvider: () => TernSecureClientProvider
58
- });
59
- function TernSecureClientProvider({ children }) {
60
- const contextValue = import_react2.default.useMemo(
61
- () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),
62
- []
63
- );
64
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TernSecureContext.Provider, { value: contextValue, children });
65
- }
66
- var import_react2, import_jsx_runtime;
67
- var init_TernSecureProvider = __esm({
68
- "src/app-router/client/TernSecureProvider.tsx"() {
69
- "use strict";
70
- "use client";
71
- import_react2 = __toESM(require("react"), 1);
72
- init_TernSecureCtx();
73
- import_jsx_runtime = require("react/jsx-runtime");
74
- TernSecureClientProvider.displayName = "TernSecureClientProvider";
75
- }
76
- });
77
-
78
30
  // src/index.ts
79
31
  var src_exports = {};
80
32
  __export(src_exports, {
@@ -163,72 +115,51 @@ async function signInWithEmail({
163
115
  return (0, import_auth2.signInWithEmailAndPassword)(auth2, email, password);
164
116
  }
165
117
 
166
- // src/index.ts
167
- init_TernSecureCtx();
168
- init_TernSecureProvider();
118
+ // src/boundary/TernSecureCtx.tsx
119
+ var import_react = require("react");
120
+ var INTERNAL_CONTEXT_KEY = Symbol("TERN_SECURE_CONTEXT");
121
+ var TernSecureContext = (0, import_react.createContext)(null);
122
+ var useInternalContext = (hookName) => {
123
+ const context = (0, import_react.useContext)(TernSecureContext);
124
+ if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {
125
+ throw new Error(
126
+ `${hookName || "Hook"} must be used within TernSecureProvider. Please wrap your component with TernSecureProvider.`
127
+ );
128
+ }
129
+ return context;
130
+ };
131
+
132
+ // src/app-router/client/TernSecureProvider.tsx
133
+ var import_react2 = __toESM(require("react"), 1);
134
+ var import_jsx_runtime = require("react/jsx-runtime");
135
+ function TernSecureClientProvider({ children }) {
136
+ const contextValue = import_react2.default.useMemo(
137
+ () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),
138
+ []
139
+ );
140
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TernSecureContext.Provider, { value: contextValue, children });
141
+ }
142
+ TernSecureClientProvider.displayName = "TernSecureClientProvider";
169
143
 
170
144
  // src/app-router/server/TernSecureServerProvider.tsx
171
- var import_react3 = __toESM(require("react"), 1);
172
- var import_dynamic = __toESM(require("next/dynamic"), 1);
173
145
  var import_jsx_runtime2 = require("react/jsx-runtime");
174
- var LoadingProvider = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
175
- "div",
176
- {
177
- "aria-label": "Loading authentication provider...",
178
- role: "status",
179
- style: { display: "none" }
180
- }
181
- );
182
- var TernSecureClientProvider2 = (0, import_dynamic.default)(
183
- () => Promise.resolve().then(() => (init_TernSecureProvider(), TernSecureProvider_exports)).then((mod) => mod.TernSecureClientProvider),
184
- {
185
- //ssr: false,
186
- loading: LoadingProvider
187
- // Return null or a loading indicator
188
- }
189
- );
190
- function TernSecureProvider({ children }) {
191
- const isRootLayout = import_react3.default.Children.toArray(children).some(
192
- (child) => import_react3.default.isValidElement(child) && child.type === "html"
193
- );
194
- if (isRootLayout) {
195
- return import_react3.default.Children.map(children, (child) => {
196
- if (import_react3.default.isValidElement(child) && child.type === "html") {
197
- return import_react3.default.cloneElement(
198
- child,
199
- {},
200
- import_react3.default.Children.map(child.props.children, (bodyChild) => {
201
- if (import_react3.default.isValidElement(bodyChild) && bodyChild.type === "body") {
202
- const bodyProps = bodyChild.props;
203
- return import_react3.default.cloneElement(
204
- bodyChild,
205
- {},
206
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TernSecureClientProvider2, { children: bodyProps.children })
207
- );
208
- }
209
- return bodyChild;
210
- })
211
- );
212
- }
213
- return child;
214
- });
215
- }
216
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TernSecureClientProvider2, { children });
146
+ async function TernSecureProvider({ children }) {
147
+ const output = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TernSecureClientProvider, { children });
148
+ return output;
217
149
  }
218
150
 
219
151
  // src/boundary/hooks/useAuth.ts
220
- var import_react4 = require("react");
152
+ var import_react3 = require("react");
221
153
  var import_auth3 = require("firebase/auth");
222
- init_TernSecureCtx();
223
154
  function useAuth() {
224
- const auth2 = (0, import_react4.useMemo)(() => TernSecureAuth(), []);
225
- const [authState, setAuthState] = (0, import_react4.useState)({
155
+ const auth2 = (0, import_react3.useMemo)(() => TernSecureAuth(), []);
156
+ const [authState, setAuthState] = (0, import_react3.useState)({
226
157
  loading: true,
227
158
  isSignedIn: false,
228
159
  userId: null,
229
160
  error: null
230
161
  });
231
- (0, import_react4.useEffect)(() => {
162
+ (0, import_react3.useEffect)(() => {
232
163
  const unsubscribe = (0, import_auth3.onAuthStateChanged)(auth2, (user) => {
233
164
  if (user) {
234
165
  setAuthState({
@@ -258,7 +189,7 @@ function useAuth() {
258
189
  }
259
190
 
260
191
  // src/components/sign-in.tsx
261
- var import_react5 = require("react");
192
+ var import_react4 = require("react");
262
193
 
263
194
  // src/utils/create-styles.ts
264
195
  var PREFIX = "tern";
@@ -388,10 +319,10 @@ function SignIn({
388
319
  style,
389
320
  customStyles = {}
390
321
  }) {
391
- const [email, setEmail] = (0, import_react5.useState)("");
392
- const [password, setPassword] = (0, import_react5.useState)("");
393
- const [loading, setLoading] = (0, import_react5.useState)(false);
394
- const [error, setError] = (0, import_react5.useState)("");
322
+ const [email, setEmail] = (0, import_react4.useState)("");
323
+ const [password, setPassword] = (0, import_react4.useState)("");
324
+ const [loading, setLoading] = (0, import_react4.useState)(false);
325
+ const [error, setError] = (0, import_react4.useState)("");
395
326
  const handleSubmit = async (e) => {
396
327
  e.preventDefault();
397
328
  setLoading(true);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/boundary/TernSecureCtx.tsx", "../../src/app-router/client/TernSecureProvider.tsx", "../../src/index.ts", "../../src/utils/client-init.ts", "../../src/utils/config.ts", "../../src/app-router/server/auth.ts", "../../src/app-router/server/TernSecureServerProvider.tsx", "../../src/boundary/hooks/useAuth.ts", "../../src/components/sign-in.tsx", "../../src/utils/create-styles.ts"],
4
- "sourcesContent": ["'use client'\r\n\r\nimport { createContext, useContext } from 'react'\r\n\r\n/**\r\n * Internal context type for TernSecure authentication\r\n * @internal\r\n */\r\ninterface TernSecureContextType {\r\n readonly _contextKey: symbol\r\n}\r\n\r\n/**\r\n * Internal symbol used for context validation\r\n * @internal\r\n */\r\nconst INTERNAL_CONTEXT_KEY = Symbol('TERN_SECURE_CONTEXT')\r\n\r\n/**\r\n * Context for TernSecure authentication\r\n * @internal\r\n */\r\nconst TernSecureContext = createContext<TernSecureContextType | null>(null)\r\n\r\n/**\r\n * Hook to verify that components are rendered within the TernSecure provider\r\n * @param hookName - Name of the hook being used (for better error messages)\r\n * @throws {Error} When used outside of TernSecureProvider\r\n * @internal\r\n */\r\nconst useInternalContext = (hookName?: string): TernSecureContextType => {\r\n const context = useContext(TernSecureContext)\r\n \r\n if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {\r\n throw new Error(\r\n `${hookName || 'Hook'} must be used within TernSecureProvider. ` +\r\n 'Please wrap your component with TernSecureProvider.'\r\n )\r\n }\r\n \r\n return context\r\n}\r\n\r\nexport {\r\n type TernSecureContextType,\r\n TernSecureContext,\r\n useInternalContext,\r\n INTERNAL_CONTEXT_KEY\r\n}", "'use client'\r\n\r\nimport React from 'react'\r\nimport { INTERNAL_CONTEXT_KEY, TernSecureContext, TernSecureContextType } from '../../boundary/TernSecureCtx'\r\n\r\n/**\r\n * Props for the TernSecureClientProvider component\r\n */\r\ninterface TernSecureClientProviderProps {\r\n /** React child elements to be wrapped by the provider */\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Provider component for TernSecure authentication\r\n * Must be used to wrap any components that use TernSecure hooks\r\n * \r\n * @example\r\n * ```tsx\r\n * function App() {\r\n * return (\r\n * <TernSecureClientProvider>\r\n * <YourApp />\r\n * </TernSecureClientProvider>\r\n * )\r\n * }\r\n * ```\r\n */\r\nexport function TernSecureClientProvider({ children }: TernSecureClientProviderProps): JSX.Element {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = React.useMemo<TernSecureContextType>(\r\n () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),\r\n []\r\n )\r\n\r\n return (\r\n <TernSecureContext.Provider value={contextValue}>\r\n {children}\r\n </TernSecureContext.Provider>\r\n )\r\n}\r\n\r\n// Add display name for better debugging\r\nTernSecureClientProvider.displayName = 'TernSecureClientProvider'", "export { TernSecureAuth, TernSecureFirestore, TernSecureStorage } from './utils/client-init'\r\nexport { loadFireConfig, validateConfig } from './utils/config'\r\nexport { signInWithEmail } from './app-router/server/auth'\r\nexport { TernSecureContext, useInternalContext } from './boundary/TernSecureCtx'\r\nexport { TernSecureClientProvider } from './app-router/client/TernSecureProvider'\r\nexport { TernSecureProvider } from './app-router/server/TernSecureServerProvider'\r\nexport { useAuth } from './boundary/hooks/useAuth' \r\nexport { SignIn } from './components/sign-in'", "import { initializeApp } from 'firebase/app';\r\nimport { getAuth, setPersistence, browserSessionPersistence } from 'firebase/auth';\r\nimport { getFirestore } from 'firebase/firestore';\r\nimport { getStorage } from 'firebase/storage';\r\nimport { initializeConfig} from './config';\r\n\r\n// Initialize immediately\r\nconst config = initializeConfig();\r\nconst clientApp = initializeApp(config)\r\nconst auth = getAuth(clientApp);\r\nsetPersistence(auth, browserSessionPersistence); //to change later user should be able to choose persistance\r\nconst firestore = getFirestore(clientApp);\r\nconst storage = getStorage(clientApp);\r\n\r\nexport const TernSecureAuth = () => auth;\r\nexport const TernSecureFirestore = () => firestore;\r\nexport const TernSecureStorage = () => storage;", "import { TernSecureConfig, ConfigValidationResult } from '../types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}", "import { TernSecureAuth } from '../../utils/client-init'\r\nimport { signInWithEmailAndPassword, type UserCredential } from 'firebase/auth'\r\n\r\nexport interface SignInCredentials {\r\n email: string\r\n password: string\r\n}\r\n\r\nexport async function signInWithEmail({ \r\n email, \r\n password \r\n}: SignInCredentials): Promise<UserCredential> {\r\n const auth = TernSecureAuth()\r\n return signInWithEmailAndPassword(auth, email, password)\r\n} ", "import React, { ReactNode } from 'react';\r\nimport dynamic from 'next/dynamic'\r\n\r\ninterface TernSecureProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n// Lightweight loading component\r\nconst LoadingProvider = () => (\r\n <div \r\n aria-label=\"Loading authentication provider...\" \r\n role=\"status\"\r\n style={{ display: 'none' }}\r\n />\r\n)\r\n\r\n// Dynamically import the client provider with no SSR\r\nconst TernSecureClientProvider = dynamic(\r\n () => import('../client/TernSecureProvider').then(mod => mod.TernSecureClientProvider),\r\n { \r\n //ssr: false,\r\n loading: LoadingProvider // Return null or a loading indicator\r\n }\r\n)\r\n\r\nexport function TernSecureProvider({ children }: TernSecureProviderProps) {\r\n // Check if the children contain html/body tags\r\n const isRootLayout = React.Children.toArray(children).some(\r\n child => React.isValidElement(child) && child.type === 'html'\r\n );\r\n\r\n if (isRootLayout) {\r\n // If this is the root layout, inject our provider after the body tag\r\n return React.Children.map(children, child => {\r\n if (React.isValidElement(child) && child.type === 'html') {\r\n return React.cloneElement(child, {}, \r\n React.Children.map(child.props.children, bodyChild => {\r\n if (React.isValidElement(bodyChild) && bodyChild.type === 'body') {\r\n // Type assertion to access props safely\r\n const bodyProps = bodyChild.props as { children: ReactNode };\r\n return React.cloneElement(bodyChild, {}, \r\n <TernSecureClientProvider>\r\n {bodyProps.children}\r\n </TernSecureClientProvider>\r\n );\r\n }\r\n return bodyChild;\r\n })\r\n );\r\n }\r\n return child;\r\n });\r\n }\r\n\r\n // For non-root layouts, wrap normally\r\n return <TernSecureClientProvider>{children}</TernSecureClientProvider>;\r\n}", "'use client'\r\n\r\nimport { useEffect, useState, useMemo } from 'react'\r\nimport { onAuthStateChanged } from 'firebase/auth'\r\nimport { TernSecureAuth } from '../../utils/client-init'\r\nimport { useInternalContext } from '../TernSecureCtx'\r\n\r\nexport interface AuthState {\r\n userId: string | null\r\n loading: boolean;\r\n error: Error | null;\r\n isSignedIn: boolean;\r\n}\r\n\r\nexport function useAuth() {\r\n const auth = useMemo(() => TernSecureAuth(), [])\r\n const [authState, setAuthState] = useState<AuthState>({\r\n loading: true,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n\r\n\r\n useEffect(() => {\r\n const unsubscribe = onAuthStateChanged(auth, (user) => {\r\n if (user) {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: true,\r\n userId: user.uid,\r\n error: null\r\n })\r\n } else {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n }\r\n })\r\n \r\n return () => unsubscribe()\r\n }, [auth])\r\n\r\n useInternalContext('useAuth')\r\n return {\r\n loading: authState.loading,\r\n isSignedIn: authState.isSignedIn,\r\n userId: authState.userId,\r\n error: authState.error\r\n }\r\n}", "import * as React from 'react'\r\nimport { useState } from 'react'\r\nimport { signInWithEmail } from '../app-router/server/auth'\r\nimport { styles } from '../utils/create-styles'\r\n\r\nexport interface SignInProps {\r\n onSuccess?: () => void\r\n onError?: (error: Error) => void\r\n redirectUrl?: string\r\n className?: string\r\n style?: React.CSSProperties\r\n customStyles?: {\r\n container?: string\r\n header?: string\r\n title?: string\r\n formWrapper?: string\r\n formContainer?: string\r\n form?: string\r\n input?: string\r\n button?: string\r\n errorText?: string\r\n label?: string\r\n }\r\n}\r\n\r\nexport function SignIn({ \r\n onSuccess, \r\n onError, \r\n redirectUrl,\r\n className = '',\r\n style,\r\n customStyles = {}\r\n}: SignInProps) {\r\n const [email, setEmail] = useState('')\r\n const [password, setPassword] = useState('')\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState('')\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault()\r\n setLoading(true)\r\n setError('')\r\n\r\n try {\r\n await signInWithEmail({ email, password })\r\n onSuccess?.()\r\n \r\n if (redirectUrl) {\r\n window.location.href = redirectUrl\r\n }\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to sign in'\r\n setError(errorMessage)\r\n onError?.(err instanceof Error ? err : new Error('Failed to sign in'))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={`${styles.container} ${customStyles.container || ''}`} style={style}>\r\n <div className={`${styles.header} ${customStyles.header || ''}`}>\r\n <h2 className={`${styles.title} ${customStyles.title || ''}`}>\r\n Sign in to your account\r\n </h2>\r\n </div>\r\n \r\n <div className={`${styles.formWrapper} ${customStyles.formWrapper || ''}`}>\r\n <div className={`${styles.formContainer} ${customStyles.formContainer || ''}`}>\r\n <form \r\n onSubmit={handleSubmit} \r\n className={`${styles.form} ${customStyles.form || ''} ${className}`}\r\n role=\"form\"\r\n aria-label=\"Sign in form\"\r\n >\r\n {error && (\r\n <div \r\n className={`${styles.error} ${customStyles.errorText || ''}`}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n >\r\n {error}\r\n </div>\r\n )}\r\n <div>\r\n <label htmlFor=\"email\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Email\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder=\"Enter your email\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <div>\r\n <label htmlFor=\"password\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Password\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder=\"Enter your password\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <button \r\n type=\"submit\" \r\n disabled={loading}\r\n className={`${styles.button} ${customStyles.button || ''}`}\r\n data-testid=\"sign-in-submit\"\r\n >\r\n {loading ? 'Signing in...' : 'Sign in'}\r\n </button>\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n", "'use client'\r\n\r\nconst PREFIX = 'tern'\r\n\r\n// Singleton to track style injection\r\nconst styleInjection = {\r\n isInjected: false,\r\n styleElement: null as HTMLStyleElement | null\r\n}\r\n\r\nexport const defaultClassNames = {\r\n container: `${PREFIX}-container`,\r\n header: `${PREFIX}-header`,\r\n title: `${PREFIX}-title`,\r\n formWrapper: `${PREFIX}-formWrapper`,\r\n formContainer: `${PREFIX}-formContainer`,\r\n form: `${PREFIX}-form`,\r\n label: `${PREFIX}-label`,\r\n input: `${PREFIX}-input`,\r\n button: `${PREFIX}-button`,\r\n error: `${PREFIX}-error`\r\n} as const\r\n\r\n// Create styles once and cache them\r\nfunction createStyleSheet(styles: Record<string, React.CSSProperties>) {\r\n if (typeof window === 'undefined') return defaultClassNames\r\n\r\n // Return early if styles are already injected\r\n if (styleInjection.isInjected) {\r\n return defaultClassNames\r\n }\r\n\r\n // Find existing style element or create new one\r\n let styleElement = document.querySelector<HTMLStyleElement>('[data-tern-secure]')\r\n \r\n if (!styleElement) {\r\n styleElement = document.createElement('style')\r\n styleElement.setAttribute('data-tern-secure', '')\r\n document.head.appendChild(styleElement)\r\n styleInjection.styleElement = styleElement\r\n }\r\n\r\n // Create CSS rules\r\n const cssRules = Object.entries(styles).map(([key, rules]) => {\r\n const className = defaultClassNames[key as keyof typeof defaultClassNames]\r\n const cssProperties = Object.entries(rules).map(([prop, value]) => {\r\n const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase()\r\n return `${cssProperty}: ${value};`\r\n }).join(' ')\r\n\r\n return `.${className} { ${cssProperties} }`\r\n }).join('\\n')\r\n\r\n // Insert styles only once\r\n styleElement.textContent = cssRules\r\n styleInjection.isInjected = true\r\n\r\n return defaultClassNames\r\n}\r\n\r\n// Style configuration\r\nexport const styleConfig = {\r\n container: {\r\n display: 'flex',\r\n minHeight: '100%',\r\n flex: '1',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '3rem 1.5rem'\r\n },\r\n header: {\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '28rem'\r\n },\r\n title: {\r\n marginTop: '1.5rem',\r\n textAlign: 'center',\r\n fontSize: '1.875rem',\r\n fontWeight: '700',\r\n lineHeight: '2.25rem',\r\n letterSpacing: '-0.025em',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n formWrapper: {\r\n marginTop: '2.5rem',\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '30rem'\r\n },\r\n formContainer: {\r\n padding: '3rem 1.5rem',\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',\r\n borderRadius: '0.5rem',\r\n backgroundColor: 'var(--tern-background, white)'\r\n },\r\n form: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '1rem'\r\n },\r\n label: {\r\n display: 'block',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'var(--tern-text-secondary, #374151)'\r\n },\r\n input: {\r\n marginTop: '0.25rem',\r\n display: 'block',\r\n width: '100%',\r\n padding: '0.5rem 0.75rem',\r\n borderRadius: '0.375rem',\r\n border: '1px solid var(--tern-border, #D1D5DB)',\r\n backgroundColor: 'var(--tern-input-background, white)',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n button: {\r\n display: 'flex',\r\n width: '100%',\r\n justifyContent: 'center',\r\n padding: '0.5rem 1rem',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'white',\r\n backgroundColor: 'var(--tern-primary, #2563EB)',\r\n border: 'none',\r\n borderRadius: '0.375rem',\r\n cursor: 'pointer'\r\n },\r\n error: {\r\n color: 'var(--tern-error, #DC2626)',\r\n fontSize: '0.875rem'\r\n }\r\n} as const\r\n\r\n// Export pre-created styles\r\nexport const styles = createStyleSheet(styleConfig)\r\n\r\n"],
5
- "mappings": "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",
6
- "names": ["React", "import_react", "config", "import_auth", "auth", "import_react", "import_jsx_runtime", "TernSecureClientProvider", "dynamic", "React", "import_react", "import_auth", "auth", "import_react", "styles", "import_jsx_runtime"]
3
+ "sources": ["../../src/index.ts", "../../src/utils/client-init.ts", "../../src/utils/config.ts", "../../src/app-router/server/auth.ts", "../../src/boundary/TernSecureCtx.tsx", "../../src/app-router/client/TernSecureProvider.tsx", "../../src/app-router/server/TernSecureServerProvider.tsx", "../../src/boundary/hooks/useAuth.ts", "../../src/components/sign-in.tsx", "../../src/utils/create-styles.ts"],
4
+ "sourcesContent": ["export { TernSecureAuth, TernSecureFirestore, TernSecureStorage } from './utils/client-init'\r\nexport { loadFireConfig, validateConfig } from './utils/config'\r\nexport { signInWithEmail } from './app-router/server/auth'\r\nexport { TernSecureContext, useInternalContext } from './boundary/TernSecureCtx'\r\nexport { TernSecureClientProvider } from './app-router/client/TernSecureProvider'\r\nexport { TernSecureProvider } from './app-router/server/TernSecureServerProvider'\r\nexport { useAuth } from './boundary/hooks/useAuth' \r\nexport { SignIn } from './components/sign-in'", "import { initializeApp } from 'firebase/app';\r\nimport { getAuth, setPersistence, browserSessionPersistence } from 'firebase/auth';\r\nimport { getFirestore } from 'firebase/firestore';\r\nimport { getStorage } from 'firebase/storage';\r\nimport { initializeConfig} from './config';\r\n\r\n// Initialize immediately\r\nconst config = initializeConfig();\r\nconst clientApp = initializeApp(config)\r\nconst auth = getAuth(clientApp);\r\nsetPersistence(auth, browserSessionPersistence); //to change later user should be able to choose persistance\r\nconst firestore = getFirestore(clientApp);\r\nconst storage = getStorage(clientApp);\r\n\r\nexport const TernSecureAuth = () => auth;\r\nexport const TernSecureFirestore = () => firestore;\r\nexport const TernSecureStorage = () => storage;", "import { TernSecureConfig, ConfigValidationResult } from '../types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}", "import { TernSecureAuth } from '../../utils/client-init'\r\nimport { signInWithEmailAndPassword, type UserCredential } from 'firebase/auth'\r\n\r\nexport interface SignInCredentials {\r\n email: string\r\n password: string\r\n}\r\n\r\nexport async function signInWithEmail({ \r\n email, \r\n password \r\n}: SignInCredentials): Promise<UserCredential> {\r\n const auth = TernSecureAuth()\r\n return signInWithEmailAndPassword(auth, email, password)\r\n} ", "'use client'\r\n\r\nimport { createContext, useContext } from 'react'\r\n\r\n/**\r\n * Internal context type for TernSecure authentication\r\n * @internal\r\n */\r\ninterface TernSecureContextType {\r\n readonly _contextKey: symbol\r\n}\r\n\r\n/**\r\n * Internal symbol used for context validation\r\n * @internal\r\n */\r\nconst INTERNAL_CONTEXT_KEY = Symbol('TERN_SECURE_CONTEXT')\r\n\r\n/**\r\n * Context for TernSecure authentication\r\n * @internal\r\n */\r\nconst TernSecureContext = createContext<TernSecureContextType | null>(null)\r\n\r\n/**\r\n * Hook to verify that components are rendered within the TernSecure provider\r\n * @param hookName - Name of the hook being used (for better error messages)\r\n * @throws {Error} When used outside of TernSecureProvider\r\n * @internal\r\n */\r\nconst useInternalContext = (hookName?: string): TernSecureContextType => {\r\n const context = useContext(TernSecureContext)\r\n \r\n if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {\r\n throw new Error(\r\n `${hookName || 'Hook'} must be used within TernSecureProvider. ` +\r\n 'Please wrap your component with TernSecureProvider.'\r\n )\r\n }\r\n \r\n return context\r\n}\r\n\r\nexport {\r\n type TernSecureContextType,\r\n TernSecureContext,\r\n useInternalContext,\r\n INTERNAL_CONTEXT_KEY\r\n}", "'use client'\r\n\r\nimport React from 'react'\r\nimport { INTERNAL_CONTEXT_KEY, TernSecureContext, TernSecureContextType } from '../../boundary/TernSecureCtx'\r\n\r\n/**\r\n * Props for the TernSecureClientProvider component\r\n */\r\ninterface TernSecureClientProviderProps {\r\n /** React child elements to be wrapped by the provider */\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Provider component for TernSecure authentication\r\n * Must be used to wrap any components that use TernSecure hooks\r\n * \r\n * @example\r\n * ```tsx\r\n * function App() {\r\n * return (\r\n * <TernSecureClientProvider>\r\n * <YourApp />\r\n * </TernSecureClientProvider>\r\n * )\r\n * }\r\n * ```\r\n */\r\nexport function TernSecureClientProvider({ children }: TernSecureClientProviderProps): JSX.Element {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = React.useMemo<TernSecureContextType>(\r\n () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),\r\n []\r\n )\r\n\r\n return (\r\n <TernSecureContext.Provider value={contextValue}>\r\n {children}\r\n </TernSecureContext.Provider>\r\n )\r\n}\r\n\r\n// Add display name for better debugging\r\nTernSecureClientProvider.displayName = 'TernSecureClientProvider'", "import { TernSecureClientProvider } from \"../client/TernSecureProvider\";\r\nimport React, { ReactNode } from \"react\";\r\n\r\ninterface TernSecureProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n\r\n\r\nexport async function TernSecureProvider({ children }: TernSecureProviderProps) {\r\n // Check if the children contain html/body tags\r\n const output = (\r\n <TernSecureClientProvider>\r\n {children}\r\n </TernSecureClientProvider>\r\n );\r\n\r\n // For non-root layouts, wrap normally\r\n return output;\r\n}", "'use client'\r\n\r\nimport { useEffect, useState, useMemo } from 'react'\r\nimport { onAuthStateChanged } from 'firebase/auth'\r\nimport { TernSecureAuth } from '../../utils/client-init'\r\nimport { useInternalContext } from '../TernSecureCtx'\r\n\r\nexport interface AuthState {\r\n userId: string | null\r\n loading: boolean;\r\n error: Error | null;\r\n isSignedIn: boolean;\r\n}\r\n\r\nexport function useAuth() {\r\n const auth = useMemo(() => TernSecureAuth(), [])\r\n const [authState, setAuthState] = useState<AuthState>({\r\n loading: true,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n\r\n\r\n useEffect(() => {\r\n const unsubscribe = onAuthStateChanged(auth, (user) => {\r\n if (user) {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: true,\r\n userId: user.uid,\r\n error: null\r\n })\r\n } else {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n }\r\n })\r\n \r\n return () => unsubscribe()\r\n }, [auth])\r\n\r\n useInternalContext('useAuth')\r\n return {\r\n loading: authState.loading,\r\n isSignedIn: authState.isSignedIn,\r\n userId: authState.userId,\r\n error: authState.error\r\n }\r\n}", "import * as React from 'react'\r\nimport { useState } from 'react'\r\nimport { signInWithEmail } from '../app-router/server/auth'\r\nimport { styles } from '../utils/create-styles'\r\n\r\nexport interface SignInProps {\r\n onSuccess?: () => void\r\n onError?: (error: Error) => void\r\n redirectUrl?: string\r\n className?: string\r\n style?: React.CSSProperties\r\n customStyles?: {\r\n container?: string\r\n header?: string\r\n title?: string\r\n formWrapper?: string\r\n formContainer?: string\r\n form?: string\r\n input?: string\r\n button?: string\r\n errorText?: string\r\n label?: string\r\n }\r\n}\r\n\r\nexport function SignIn({ \r\n onSuccess, \r\n onError, \r\n redirectUrl,\r\n className = '',\r\n style,\r\n customStyles = {}\r\n}: SignInProps) {\r\n const [email, setEmail] = useState('')\r\n const [password, setPassword] = useState('')\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState('')\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault()\r\n setLoading(true)\r\n setError('')\r\n\r\n try {\r\n await signInWithEmail({ email, password })\r\n onSuccess?.()\r\n \r\n if (redirectUrl) {\r\n window.location.href = redirectUrl\r\n }\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to sign in'\r\n setError(errorMessage)\r\n onError?.(err instanceof Error ? err : new Error('Failed to sign in'))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={`${styles.container} ${customStyles.container || ''}`} style={style}>\r\n <div className={`${styles.header} ${customStyles.header || ''}`}>\r\n <h2 className={`${styles.title} ${customStyles.title || ''}`}>\r\n Sign in to your account\r\n </h2>\r\n </div>\r\n \r\n <div className={`${styles.formWrapper} ${customStyles.formWrapper || ''}`}>\r\n <div className={`${styles.formContainer} ${customStyles.formContainer || ''}`}>\r\n <form \r\n onSubmit={handleSubmit} \r\n className={`${styles.form} ${customStyles.form || ''} ${className}`}\r\n role=\"form\"\r\n aria-label=\"Sign in form\"\r\n >\r\n {error && (\r\n <div \r\n className={`${styles.error} ${customStyles.errorText || ''}`}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n >\r\n {error}\r\n </div>\r\n )}\r\n <div>\r\n <label htmlFor=\"email\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Email\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder=\"Enter your email\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <div>\r\n <label htmlFor=\"password\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Password\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder=\"Enter your password\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <button \r\n type=\"submit\" \r\n disabled={loading}\r\n className={`${styles.button} ${customStyles.button || ''}`}\r\n data-testid=\"sign-in-submit\"\r\n >\r\n {loading ? 'Signing in...' : 'Sign in'}\r\n </button>\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n", "'use client'\r\n\r\nconst PREFIX = 'tern'\r\n\r\n// Singleton to track style injection\r\nconst styleInjection = {\r\n isInjected: false,\r\n styleElement: null as HTMLStyleElement | null\r\n}\r\n\r\nexport const defaultClassNames = {\r\n container: `${PREFIX}-container`,\r\n header: `${PREFIX}-header`,\r\n title: `${PREFIX}-title`,\r\n formWrapper: `${PREFIX}-formWrapper`,\r\n formContainer: `${PREFIX}-formContainer`,\r\n form: `${PREFIX}-form`,\r\n label: `${PREFIX}-label`,\r\n input: `${PREFIX}-input`,\r\n button: `${PREFIX}-button`,\r\n error: `${PREFIX}-error`\r\n} as const\r\n\r\n// Create styles once and cache them\r\nfunction createStyleSheet(styles: Record<string, React.CSSProperties>) {\r\n if (typeof window === 'undefined') return defaultClassNames\r\n\r\n // Return early if styles are already injected\r\n if (styleInjection.isInjected) {\r\n return defaultClassNames\r\n }\r\n\r\n // Find existing style element or create new one\r\n let styleElement = document.querySelector<HTMLStyleElement>('[data-tern-secure]')\r\n \r\n if (!styleElement) {\r\n styleElement = document.createElement('style')\r\n styleElement.setAttribute('data-tern-secure', '')\r\n document.head.appendChild(styleElement)\r\n styleInjection.styleElement = styleElement\r\n }\r\n\r\n // Create CSS rules\r\n const cssRules = Object.entries(styles).map(([key, rules]) => {\r\n const className = defaultClassNames[key as keyof typeof defaultClassNames]\r\n const cssProperties = Object.entries(rules).map(([prop, value]) => {\r\n const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase()\r\n return `${cssProperty}: ${value};`\r\n }).join(' ')\r\n\r\n return `.${className} { ${cssProperties} }`\r\n }).join('\\n')\r\n\r\n // Insert styles only once\r\n styleElement.textContent = cssRules\r\n styleInjection.isInjected = true\r\n\r\n return defaultClassNames\r\n}\r\n\r\n// Style configuration\r\nexport const styleConfig = {\r\n container: {\r\n display: 'flex',\r\n minHeight: '100%',\r\n flex: '1',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '3rem 1.5rem'\r\n },\r\n header: {\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '28rem'\r\n },\r\n title: {\r\n marginTop: '1.5rem',\r\n textAlign: 'center',\r\n fontSize: '1.875rem',\r\n fontWeight: '700',\r\n lineHeight: '2.25rem',\r\n letterSpacing: '-0.025em',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n formWrapper: {\r\n marginTop: '2.5rem',\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '30rem'\r\n },\r\n formContainer: {\r\n padding: '3rem 1.5rem',\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',\r\n borderRadius: '0.5rem',\r\n backgroundColor: 'var(--tern-background, white)'\r\n },\r\n form: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '1rem'\r\n },\r\n label: {\r\n display: 'block',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'var(--tern-text-secondary, #374151)'\r\n },\r\n input: {\r\n marginTop: '0.25rem',\r\n display: 'block',\r\n width: '100%',\r\n padding: '0.5rem 0.75rem',\r\n borderRadius: '0.375rem',\r\n border: '1px solid var(--tern-border, #D1D5DB)',\r\n backgroundColor: 'var(--tern-input-background, white)',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n button: {\r\n display: 'flex',\r\n width: '100%',\r\n justifyContent: 'center',\r\n padding: '0.5rem 1rem',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'white',\r\n backgroundColor: 'var(--tern-primary, #2563EB)',\r\n border: 'none',\r\n borderRadius: '0.375rem',\r\n cursor: 'pointer'\r\n },\r\n error: {\r\n color: 'var(--tern-error, #DC2626)',\r\n fontSize: '0.875rem'\r\n }\r\n} as const\r\n\r\n// Export pre-created styles\r\nexport const styles = createStyleSheet(styleConfig)\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": ["config", "import_auth", "auth", "import_react", "React", "import_jsx_runtime", "import_react", "import_auth", "auth", "import_react", "styles", "import_jsx_runtime"]
7
7
  }
@@ -1,7 +1,7 @@
1
- import React, { ReactNode } from 'react';
1
+ import { ReactNode } from "react";
2
2
  interface TernSecureProviderProps {
3
3
  children: ReactNode;
4
4
  }
5
- export declare function TernSecureProvider({ children }: TernSecureProviderProps): import("react/jsx-runtime").JSX.Element | (string | number | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode>)[] | null | undefined;
5
+ export declare function TernSecureProvider({ children }: TernSecureProviderProps): Promise<import("react/jsx-runtime").JSX.Element>;
6
6
  export {};
7
7
  //# sourceMappingURL=TernSecureServerProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TernSecureServerProvider.d.ts","sourceRoot":"","sources":["../../../../src/app-router/server/TernSecureServerProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGzC,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAoBD,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,uBAAuB,qLA+BvE"}
1
+ {"version":3,"file":"TernSecureServerProvider.d.ts","sourceRoot":"","sources":["../../../../src/app-router/server/TernSecureServerProvider.tsx"],"names":[],"mappings":"AACA,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID,wBAAsB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,uBAAuB,oDAU7E"}
package/dist/esm/index.js CHANGED
@@ -1,9 +1,3 @@
1
- import {
2
- TernSecureClientProvider,
3
- TernSecureContext,
4
- useInternalContext
5
- } from "./chunk-Q7WUJODD.js";
6
-
7
1
  // src/utils/client-init.ts
8
2
  import { initializeApp } from "firebase/app";
9
3
  import { getAuth, setPersistence, browserSessionPersistence } from "firebase/auth";
@@ -74,53 +68,37 @@ async function signInWithEmail({
74
68
  return signInWithEmailAndPassword(auth2, email, password);
75
69
  }
76
70
 
77
- // src/app-router/server/TernSecureServerProvider.tsx
71
+ // src/boundary/TernSecureCtx.tsx
72
+ import { createContext, useContext } from "react";
73
+ var INTERNAL_CONTEXT_KEY = Symbol("TERN_SECURE_CONTEXT");
74
+ var TernSecureContext = createContext(null);
75
+ var useInternalContext = (hookName) => {
76
+ const context = useContext(TernSecureContext);
77
+ if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {
78
+ throw new Error(
79
+ `${hookName || "Hook"} must be used within TernSecureProvider. Please wrap your component with TernSecureProvider.`
80
+ );
81
+ }
82
+ return context;
83
+ };
84
+
85
+ // src/app-router/client/TernSecureProvider.tsx
78
86
  import React from "react";
79
- import dynamic from "next/dynamic";
80
87
  import { jsx } from "react/jsx-runtime";
81
- var LoadingProvider = () => /* @__PURE__ */ jsx(
82
- "div",
83
- {
84
- "aria-label": "Loading authentication provider...",
85
- role: "status",
86
- style: { display: "none" }
87
- }
88
- );
89
- var TernSecureClientProvider2 = dynamic(
90
- () => import("./TernSecureProvider-7KNRQUY2.js").then((mod) => mod.TernSecureClientProvider),
91
- {
92
- //ssr: false,
93
- loading: LoadingProvider
94
- // Return null or a loading indicator
95
- }
96
- );
97
- function TernSecureProvider({ children }) {
98
- const isRootLayout = React.Children.toArray(children).some(
99
- (child) => React.isValidElement(child) && child.type === "html"
88
+ function TernSecureClientProvider({ children }) {
89
+ const contextValue = React.useMemo(
90
+ () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),
91
+ []
100
92
  );
101
- if (isRootLayout) {
102
- return React.Children.map(children, (child) => {
103
- if (React.isValidElement(child) && child.type === "html") {
104
- return React.cloneElement(
105
- child,
106
- {},
107
- React.Children.map(child.props.children, (bodyChild) => {
108
- if (React.isValidElement(bodyChild) && bodyChild.type === "body") {
109
- const bodyProps = bodyChild.props;
110
- return React.cloneElement(
111
- bodyChild,
112
- {},
113
- /* @__PURE__ */ jsx(TernSecureClientProvider2, { children: bodyProps.children })
114
- );
115
- }
116
- return bodyChild;
117
- })
118
- );
119
- }
120
- return child;
121
- });
122
- }
123
- return /* @__PURE__ */ jsx(TernSecureClientProvider2, { children });
93
+ return /* @__PURE__ */ jsx(TernSecureContext.Provider, { value: contextValue, children });
94
+ }
95
+ TernSecureClientProvider.displayName = "TernSecureClientProvider";
96
+
97
+ // src/app-router/server/TernSecureServerProvider.tsx
98
+ import { jsx as jsx2 } from "react/jsx-runtime";
99
+ async function TernSecureProvider({ children }) {
100
+ const output = /* @__PURE__ */ jsx2(TernSecureClientProvider, { children });
101
+ return output;
124
102
  }
125
103
 
126
104
  // src/boundary/hooks/useAuth.ts
@@ -285,7 +263,7 @@ var styleConfig = {
285
263
  var styles = createStyleSheet(styleConfig);
286
264
 
287
265
  // src/components/sign-in.tsx
288
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
266
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
289
267
  function SignIn({
290
268
  onSuccess,
291
269
  onError,
@@ -317,8 +295,8 @@ function SignIn({
317
295
  }
318
296
  };
319
297
  return /* @__PURE__ */ jsxs("div", { className: `${styles.container} ${customStyles.container || ""}`, style, children: [
320
- /* @__PURE__ */ jsx2("div", { className: `${styles.header} ${customStyles.header || ""}`, children: /* @__PURE__ */ jsx2("h2", { className: `${styles.title} ${customStyles.title || ""}`, children: "Sign in to your account" }) }),
321
- /* @__PURE__ */ jsx2("div", { className: `${styles.formWrapper} ${customStyles.formWrapper || ""}`, children: /* @__PURE__ */ jsx2("div", { className: `${styles.formContainer} ${customStyles.formContainer || ""}`, children: /* @__PURE__ */ jsxs(
298
+ /* @__PURE__ */ jsx3("div", { className: `${styles.header} ${customStyles.header || ""}`, children: /* @__PURE__ */ jsx3("h2", { className: `${styles.title} ${customStyles.title || ""}`, children: "Sign in to your account" }) }),
299
+ /* @__PURE__ */ jsx3("div", { className: `${styles.formWrapper} ${customStyles.formWrapper || ""}`, children: /* @__PURE__ */ jsx3("div", { className: `${styles.formContainer} ${customStyles.formContainer || ""}`, children: /* @__PURE__ */ jsxs(
322
300
  "form",
323
301
  {
324
302
  onSubmit: handleSubmit,
@@ -326,7 +304,7 @@ function SignIn({
326
304
  role: "form",
327
305
  "aria-label": "Sign in form",
328
306
  children: [
329
- error && /* @__PURE__ */ jsx2(
307
+ error && /* @__PURE__ */ jsx3(
330
308
  "div",
331
309
  {
332
310
  className: `${styles.error} ${customStyles.errorText || ""}`,
@@ -336,8 +314,8 @@ function SignIn({
336
314
  }
337
315
  ),
338
316
  /* @__PURE__ */ jsxs("div", { children: [
339
- /* @__PURE__ */ jsx2("label", { htmlFor: "email", className: `${styles.label} ${customStyles.label || ""}`, children: "Email" }),
340
- /* @__PURE__ */ jsx2(
317
+ /* @__PURE__ */ jsx3("label", { htmlFor: "email", className: `${styles.label} ${customStyles.label || ""}`, children: "Email" }),
318
+ /* @__PURE__ */ jsx3(
341
319
  "input",
342
320
  {
343
321
  id: "email",
@@ -354,8 +332,8 @@ function SignIn({
354
332
  )
355
333
  ] }),
356
334
  /* @__PURE__ */ jsxs("div", { children: [
357
- /* @__PURE__ */ jsx2("label", { htmlFor: "password", className: `${styles.label} ${customStyles.label || ""}`, children: "Password" }),
358
- /* @__PURE__ */ jsx2(
335
+ /* @__PURE__ */ jsx3("label", { htmlFor: "password", className: `${styles.label} ${customStyles.label || ""}`, children: "Password" }),
336
+ /* @__PURE__ */ jsx3(
359
337
  "input",
360
338
  {
361
339
  id: "password",
@@ -371,7 +349,7 @@ function SignIn({
371
349
  }
372
350
  )
373
351
  ] }),
374
- /* @__PURE__ */ jsx2(
352
+ /* @__PURE__ */ jsx3(
375
353
  "button",
376
354
  {
377
355
  type: "submit",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/utils/client-init.ts", "../../src/utils/config.ts", "../../src/app-router/server/auth.ts", "../../src/app-router/server/TernSecureServerProvider.tsx", "../../src/boundary/hooks/useAuth.ts", "../../src/components/sign-in.tsx", "../../src/utils/create-styles.ts"],
4
- "sourcesContent": ["import { initializeApp } from 'firebase/app';\r\nimport { getAuth, setPersistence, browserSessionPersistence } from 'firebase/auth';\r\nimport { getFirestore } from 'firebase/firestore';\r\nimport { getStorage } from 'firebase/storage';\r\nimport { initializeConfig} from './config';\r\n\r\n// Initialize immediately\r\nconst config = initializeConfig();\r\nconst clientApp = initializeApp(config)\r\nconst auth = getAuth(clientApp);\r\nsetPersistence(auth, browserSessionPersistence); //to change later user should be able to choose persistance\r\nconst firestore = getFirestore(clientApp);\r\nconst storage = getStorage(clientApp);\r\n\r\nexport const TernSecureAuth = () => auth;\r\nexport const TernSecureFirestore = () => firestore;\r\nexport const TernSecureStorage = () => storage;", "import { TernSecureConfig, ConfigValidationResult } from '../types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}", "import { TernSecureAuth } from '../../utils/client-init'\r\nimport { signInWithEmailAndPassword, type UserCredential } from 'firebase/auth'\r\n\r\nexport interface SignInCredentials {\r\n email: string\r\n password: string\r\n}\r\n\r\nexport async function signInWithEmail({ \r\n email, \r\n password \r\n}: SignInCredentials): Promise<UserCredential> {\r\n const auth = TernSecureAuth()\r\n return signInWithEmailAndPassword(auth, email, password)\r\n} ", "import React, { ReactNode } from 'react';\r\nimport dynamic from 'next/dynamic'\r\n\r\ninterface TernSecureProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n// Lightweight loading component\r\nconst LoadingProvider = () => (\r\n <div \r\n aria-label=\"Loading authentication provider...\" \r\n role=\"status\"\r\n style={{ display: 'none' }}\r\n />\r\n)\r\n\r\n// Dynamically import the client provider with no SSR\r\nconst TernSecureClientProvider = dynamic(\r\n () => import('../client/TernSecureProvider').then(mod => mod.TernSecureClientProvider),\r\n { \r\n //ssr: false,\r\n loading: LoadingProvider // Return null or a loading indicator\r\n }\r\n)\r\n\r\nexport function TernSecureProvider({ children }: TernSecureProviderProps) {\r\n // Check if the children contain html/body tags\r\n const isRootLayout = React.Children.toArray(children).some(\r\n child => React.isValidElement(child) && child.type === 'html'\r\n );\r\n\r\n if (isRootLayout) {\r\n // If this is the root layout, inject our provider after the body tag\r\n return React.Children.map(children, child => {\r\n if (React.isValidElement(child) && child.type === 'html') {\r\n return React.cloneElement(child, {}, \r\n React.Children.map(child.props.children, bodyChild => {\r\n if (React.isValidElement(bodyChild) && bodyChild.type === 'body') {\r\n // Type assertion to access props safely\r\n const bodyProps = bodyChild.props as { children: ReactNode };\r\n return React.cloneElement(bodyChild, {}, \r\n <TernSecureClientProvider>\r\n {bodyProps.children}\r\n </TernSecureClientProvider>\r\n );\r\n }\r\n return bodyChild;\r\n })\r\n );\r\n }\r\n return child;\r\n });\r\n }\r\n\r\n // For non-root layouts, wrap normally\r\n return <TernSecureClientProvider>{children}</TernSecureClientProvider>;\r\n}", "'use client'\r\n\r\nimport { useEffect, useState, useMemo } from 'react'\r\nimport { onAuthStateChanged } from 'firebase/auth'\r\nimport { TernSecureAuth } from '../../utils/client-init'\r\nimport { useInternalContext } from '../TernSecureCtx'\r\n\r\nexport interface AuthState {\r\n userId: string | null\r\n loading: boolean;\r\n error: Error | null;\r\n isSignedIn: boolean;\r\n}\r\n\r\nexport function useAuth() {\r\n const auth = useMemo(() => TernSecureAuth(), [])\r\n const [authState, setAuthState] = useState<AuthState>({\r\n loading: true,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n\r\n\r\n useEffect(() => {\r\n const unsubscribe = onAuthStateChanged(auth, (user) => {\r\n if (user) {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: true,\r\n userId: user.uid,\r\n error: null\r\n })\r\n } else {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n }\r\n })\r\n \r\n return () => unsubscribe()\r\n }, [auth])\r\n\r\n useInternalContext('useAuth')\r\n return {\r\n loading: authState.loading,\r\n isSignedIn: authState.isSignedIn,\r\n userId: authState.userId,\r\n error: authState.error\r\n }\r\n}", "import * as React from 'react'\r\nimport { useState } from 'react'\r\nimport { signInWithEmail } from '../app-router/server/auth'\r\nimport { styles } from '../utils/create-styles'\r\n\r\nexport interface SignInProps {\r\n onSuccess?: () => void\r\n onError?: (error: Error) => void\r\n redirectUrl?: string\r\n className?: string\r\n style?: React.CSSProperties\r\n customStyles?: {\r\n container?: string\r\n header?: string\r\n title?: string\r\n formWrapper?: string\r\n formContainer?: string\r\n form?: string\r\n input?: string\r\n button?: string\r\n errorText?: string\r\n label?: string\r\n }\r\n}\r\n\r\nexport function SignIn({ \r\n onSuccess, \r\n onError, \r\n redirectUrl,\r\n className = '',\r\n style,\r\n customStyles = {}\r\n}: SignInProps) {\r\n const [email, setEmail] = useState('')\r\n const [password, setPassword] = useState('')\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState('')\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault()\r\n setLoading(true)\r\n setError('')\r\n\r\n try {\r\n await signInWithEmail({ email, password })\r\n onSuccess?.()\r\n \r\n if (redirectUrl) {\r\n window.location.href = redirectUrl\r\n }\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to sign in'\r\n setError(errorMessage)\r\n onError?.(err instanceof Error ? err : new Error('Failed to sign in'))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={`${styles.container} ${customStyles.container || ''}`} style={style}>\r\n <div className={`${styles.header} ${customStyles.header || ''}`}>\r\n <h2 className={`${styles.title} ${customStyles.title || ''}`}>\r\n Sign in to your account\r\n </h2>\r\n </div>\r\n \r\n <div className={`${styles.formWrapper} ${customStyles.formWrapper || ''}`}>\r\n <div className={`${styles.formContainer} ${customStyles.formContainer || ''}`}>\r\n <form \r\n onSubmit={handleSubmit} \r\n className={`${styles.form} ${customStyles.form || ''} ${className}`}\r\n role=\"form\"\r\n aria-label=\"Sign in form\"\r\n >\r\n {error && (\r\n <div \r\n className={`${styles.error} ${customStyles.errorText || ''}`}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n >\r\n {error}\r\n </div>\r\n )}\r\n <div>\r\n <label htmlFor=\"email\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Email\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder=\"Enter your email\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <div>\r\n <label htmlFor=\"password\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Password\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder=\"Enter your password\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <button \r\n type=\"submit\" \r\n disabled={loading}\r\n className={`${styles.button} ${customStyles.button || ''}`}\r\n data-testid=\"sign-in-submit\"\r\n >\r\n {loading ? 'Signing in...' : 'Sign in'}\r\n </button>\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n", "'use client'\r\n\r\nconst PREFIX = 'tern'\r\n\r\n// Singleton to track style injection\r\nconst styleInjection = {\r\n isInjected: false,\r\n styleElement: null as HTMLStyleElement | null\r\n}\r\n\r\nexport const defaultClassNames = {\r\n container: `${PREFIX}-container`,\r\n header: `${PREFIX}-header`,\r\n title: `${PREFIX}-title`,\r\n formWrapper: `${PREFIX}-formWrapper`,\r\n formContainer: `${PREFIX}-formContainer`,\r\n form: `${PREFIX}-form`,\r\n label: `${PREFIX}-label`,\r\n input: `${PREFIX}-input`,\r\n button: `${PREFIX}-button`,\r\n error: `${PREFIX}-error`\r\n} as const\r\n\r\n// Create styles once and cache them\r\nfunction createStyleSheet(styles: Record<string, React.CSSProperties>) {\r\n if (typeof window === 'undefined') return defaultClassNames\r\n\r\n // Return early if styles are already injected\r\n if (styleInjection.isInjected) {\r\n return defaultClassNames\r\n }\r\n\r\n // Find existing style element or create new one\r\n let styleElement = document.querySelector<HTMLStyleElement>('[data-tern-secure]')\r\n \r\n if (!styleElement) {\r\n styleElement = document.createElement('style')\r\n styleElement.setAttribute('data-tern-secure', '')\r\n document.head.appendChild(styleElement)\r\n styleInjection.styleElement = styleElement\r\n }\r\n\r\n // Create CSS rules\r\n const cssRules = Object.entries(styles).map(([key, rules]) => {\r\n const className = defaultClassNames[key as keyof typeof defaultClassNames]\r\n const cssProperties = Object.entries(rules).map(([prop, value]) => {\r\n const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase()\r\n return `${cssProperty}: ${value};`\r\n }).join(' ')\r\n\r\n return `.${className} { ${cssProperties} }`\r\n }).join('\\n')\r\n\r\n // Insert styles only once\r\n styleElement.textContent = cssRules\r\n styleInjection.isInjected = true\r\n\r\n return defaultClassNames\r\n}\r\n\r\n// Style configuration\r\nexport const styleConfig = {\r\n container: {\r\n display: 'flex',\r\n minHeight: '100%',\r\n flex: '1',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '3rem 1.5rem'\r\n },\r\n header: {\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '28rem'\r\n },\r\n title: {\r\n marginTop: '1.5rem',\r\n textAlign: 'center',\r\n fontSize: '1.875rem',\r\n fontWeight: '700',\r\n lineHeight: '2.25rem',\r\n letterSpacing: '-0.025em',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n formWrapper: {\r\n marginTop: '2.5rem',\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '30rem'\r\n },\r\n formContainer: {\r\n padding: '3rem 1.5rem',\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',\r\n borderRadius: '0.5rem',\r\n backgroundColor: 'var(--tern-background, white)'\r\n },\r\n form: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '1rem'\r\n },\r\n label: {\r\n display: 'block',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'var(--tern-text-secondary, #374151)'\r\n },\r\n input: {\r\n marginTop: '0.25rem',\r\n display: 'block',\r\n width: '100%',\r\n padding: '0.5rem 0.75rem',\r\n borderRadius: '0.375rem',\r\n border: '1px solid var(--tern-border, #D1D5DB)',\r\n backgroundColor: 'var(--tern-input-background, white)',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n button: {\r\n display: 'flex',\r\n width: '100%',\r\n justifyContent: 'center',\r\n padding: '0.5rem 1rem',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'white',\r\n backgroundColor: 'var(--tern-primary, #2563EB)',\r\n border: 'none',\r\n borderRadius: '0.375rem',\r\n cursor: 'pointer'\r\n },\r\n error: {\r\n color: 'var(--tern-error, #DC2626)',\r\n fontSize: '0.875rem'\r\n }\r\n} as const\r\n\r\n// Export pre-created styles\r\nexport const styles = createStyleSheet(styleConfig)\r\n\r\n"],
5
- "mappings": "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",
6
- "names": ["config", "auth", "TernSecureClientProvider", "auth", "useState", "styles", "jsx", "useState"]
3
+ "sources": ["../../src/utils/client-init.ts", "../../src/utils/config.ts", "../../src/app-router/server/auth.ts", "../../src/boundary/TernSecureCtx.tsx", "../../src/app-router/client/TernSecureProvider.tsx", "../../src/app-router/server/TernSecureServerProvider.tsx", "../../src/boundary/hooks/useAuth.ts", "../../src/components/sign-in.tsx", "../../src/utils/create-styles.ts"],
4
+ "sourcesContent": ["import { initializeApp } from 'firebase/app';\r\nimport { getAuth, setPersistence, browserSessionPersistence } from 'firebase/auth';\r\nimport { getFirestore } from 'firebase/firestore';\r\nimport { getStorage } from 'firebase/storage';\r\nimport { initializeConfig} from './config';\r\n\r\n// Initialize immediately\r\nconst config = initializeConfig();\r\nconst clientApp = initializeApp(config)\r\nconst auth = getAuth(clientApp);\r\nsetPersistence(auth, browserSessionPersistence); //to change later user should be able to choose persistance\r\nconst firestore = getFirestore(clientApp);\r\nconst storage = getStorage(clientApp);\r\n\r\nexport const TernSecureAuth = () => auth;\r\nexport const TernSecureFirestore = () => firestore;\r\nexport const TernSecureStorage = () => storage;", "import { TernSecureConfig, ConfigValidationResult } from '../types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}", "import { TernSecureAuth } from '../../utils/client-init'\r\nimport { signInWithEmailAndPassword, type UserCredential } from 'firebase/auth'\r\n\r\nexport interface SignInCredentials {\r\n email: string\r\n password: string\r\n}\r\n\r\nexport async function signInWithEmail({ \r\n email, \r\n password \r\n}: SignInCredentials): Promise<UserCredential> {\r\n const auth = TernSecureAuth()\r\n return signInWithEmailAndPassword(auth, email, password)\r\n} ", "'use client'\r\n\r\nimport { createContext, useContext } from 'react'\r\n\r\n/**\r\n * Internal context type for TernSecure authentication\r\n * @internal\r\n */\r\ninterface TernSecureContextType {\r\n readonly _contextKey: symbol\r\n}\r\n\r\n/**\r\n * Internal symbol used for context validation\r\n * @internal\r\n */\r\nconst INTERNAL_CONTEXT_KEY = Symbol('TERN_SECURE_CONTEXT')\r\n\r\n/**\r\n * Context for TernSecure authentication\r\n * @internal\r\n */\r\nconst TernSecureContext = createContext<TernSecureContextType | null>(null)\r\n\r\n/**\r\n * Hook to verify that components are rendered within the TernSecure provider\r\n * @param hookName - Name of the hook being used (for better error messages)\r\n * @throws {Error} When used outside of TernSecureProvider\r\n * @internal\r\n */\r\nconst useInternalContext = (hookName?: string): TernSecureContextType => {\r\n const context = useContext(TernSecureContext)\r\n \r\n if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {\r\n throw new Error(\r\n `${hookName || 'Hook'} must be used within TernSecureProvider. ` +\r\n 'Please wrap your component with TernSecureProvider.'\r\n )\r\n }\r\n \r\n return context\r\n}\r\n\r\nexport {\r\n type TernSecureContextType,\r\n TernSecureContext,\r\n useInternalContext,\r\n INTERNAL_CONTEXT_KEY\r\n}", "'use client'\r\n\r\nimport React from 'react'\r\nimport { INTERNAL_CONTEXT_KEY, TernSecureContext, TernSecureContextType } from '../../boundary/TernSecureCtx'\r\n\r\n/**\r\n * Props for the TernSecureClientProvider component\r\n */\r\ninterface TernSecureClientProviderProps {\r\n /** React child elements to be wrapped by the provider */\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Provider component for TernSecure authentication\r\n * Must be used to wrap any components that use TernSecure hooks\r\n * \r\n * @example\r\n * ```tsx\r\n * function App() {\r\n * return (\r\n * <TernSecureClientProvider>\r\n * <YourApp />\r\n * </TernSecureClientProvider>\r\n * )\r\n * }\r\n * ```\r\n */\r\nexport function TernSecureClientProvider({ children }: TernSecureClientProviderProps): JSX.Element {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = React.useMemo<TernSecureContextType>(\r\n () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),\r\n []\r\n )\r\n\r\n return (\r\n <TernSecureContext.Provider value={contextValue}>\r\n {children}\r\n </TernSecureContext.Provider>\r\n )\r\n}\r\n\r\n// Add display name for better debugging\r\nTernSecureClientProvider.displayName = 'TernSecureClientProvider'", "import { TernSecureClientProvider } from \"../client/TernSecureProvider\";\r\nimport React, { ReactNode } from \"react\";\r\n\r\ninterface TernSecureProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\n\r\n\r\nexport async function TernSecureProvider({ children }: TernSecureProviderProps) {\r\n // Check if the children contain html/body tags\r\n const output = (\r\n <TernSecureClientProvider>\r\n {children}\r\n </TernSecureClientProvider>\r\n );\r\n\r\n // For non-root layouts, wrap normally\r\n return output;\r\n}", "'use client'\r\n\r\nimport { useEffect, useState, useMemo } from 'react'\r\nimport { onAuthStateChanged } from 'firebase/auth'\r\nimport { TernSecureAuth } from '../../utils/client-init'\r\nimport { useInternalContext } from '../TernSecureCtx'\r\n\r\nexport interface AuthState {\r\n userId: string | null\r\n loading: boolean;\r\n error: Error | null;\r\n isSignedIn: boolean;\r\n}\r\n\r\nexport function useAuth() {\r\n const auth = useMemo(() => TernSecureAuth(), [])\r\n const [authState, setAuthState] = useState<AuthState>({\r\n loading: true,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n\r\n\r\n useEffect(() => {\r\n const unsubscribe = onAuthStateChanged(auth, (user) => {\r\n if (user) {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: true,\r\n userId: user.uid,\r\n error: null\r\n })\r\n } else {\r\n setAuthState({\r\n loading: false,\r\n isSignedIn: false,\r\n userId: null,\r\n error: null\r\n })\r\n }\r\n })\r\n \r\n return () => unsubscribe()\r\n }, [auth])\r\n\r\n useInternalContext('useAuth')\r\n return {\r\n loading: authState.loading,\r\n isSignedIn: authState.isSignedIn,\r\n userId: authState.userId,\r\n error: authState.error\r\n }\r\n}", "import * as React from 'react'\r\nimport { useState } from 'react'\r\nimport { signInWithEmail } from '../app-router/server/auth'\r\nimport { styles } from '../utils/create-styles'\r\n\r\nexport interface SignInProps {\r\n onSuccess?: () => void\r\n onError?: (error: Error) => void\r\n redirectUrl?: string\r\n className?: string\r\n style?: React.CSSProperties\r\n customStyles?: {\r\n container?: string\r\n header?: string\r\n title?: string\r\n formWrapper?: string\r\n formContainer?: string\r\n form?: string\r\n input?: string\r\n button?: string\r\n errorText?: string\r\n label?: string\r\n }\r\n}\r\n\r\nexport function SignIn({ \r\n onSuccess, \r\n onError, \r\n redirectUrl,\r\n className = '',\r\n style,\r\n customStyles = {}\r\n}: SignInProps) {\r\n const [email, setEmail] = useState('')\r\n const [password, setPassword] = useState('')\r\n const [loading, setLoading] = useState(false)\r\n const [error, setError] = useState('')\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault()\r\n setLoading(true)\r\n setError('')\r\n\r\n try {\r\n await signInWithEmail({ email, password })\r\n onSuccess?.()\r\n \r\n if (redirectUrl) {\r\n window.location.href = redirectUrl\r\n }\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to sign in'\r\n setError(errorMessage)\r\n onError?.(err instanceof Error ? err : new Error('Failed to sign in'))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={`${styles.container} ${customStyles.container || ''}`} style={style}>\r\n <div className={`${styles.header} ${customStyles.header || ''}`}>\r\n <h2 className={`${styles.title} ${customStyles.title || ''}`}>\r\n Sign in to your account\r\n </h2>\r\n </div>\r\n \r\n <div className={`${styles.formWrapper} ${customStyles.formWrapper || ''}`}>\r\n <div className={`${styles.formContainer} ${customStyles.formContainer || ''}`}>\r\n <form \r\n onSubmit={handleSubmit} \r\n className={`${styles.form} ${customStyles.form || ''} ${className}`}\r\n role=\"form\"\r\n aria-label=\"Sign in form\"\r\n >\r\n {error && (\r\n <div \r\n className={`${styles.error} ${customStyles.errorText || ''}`}\r\n role=\"alert\"\r\n aria-live=\"polite\"\r\n >\r\n {error}\r\n </div>\r\n )}\r\n <div>\r\n <label htmlFor=\"email\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Email\r\n </label>\r\n <input\r\n id=\"email\"\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder=\"Enter your email\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <div>\r\n <label htmlFor=\"password\" className={`${styles.label} ${customStyles.label || ''}`}>\r\n Password\r\n </label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n placeholder=\"Enter your password\"\r\n required\r\n className={`${styles.input} ${customStyles.input || ''}`}\r\n disabled={loading}\r\n aria-required=\"true\"\r\n aria-invalid={!!error}\r\n />\r\n </div>\r\n <button \r\n type=\"submit\" \r\n disabled={loading}\r\n className={`${styles.button} ${customStyles.button || ''}`}\r\n data-testid=\"sign-in-submit\"\r\n >\r\n {loading ? 'Signing in...' : 'Sign in'}\r\n </button>\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n", "'use client'\r\n\r\nconst PREFIX = 'tern'\r\n\r\n// Singleton to track style injection\r\nconst styleInjection = {\r\n isInjected: false,\r\n styleElement: null as HTMLStyleElement | null\r\n}\r\n\r\nexport const defaultClassNames = {\r\n container: `${PREFIX}-container`,\r\n header: `${PREFIX}-header`,\r\n title: `${PREFIX}-title`,\r\n formWrapper: `${PREFIX}-formWrapper`,\r\n formContainer: `${PREFIX}-formContainer`,\r\n form: `${PREFIX}-form`,\r\n label: `${PREFIX}-label`,\r\n input: `${PREFIX}-input`,\r\n button: `${PREFIX}-button`,\r\n error: `${PREFIX}-error`\r\n} as const\r\n\r\n// Create styles once and cache them\r\nfunction createStyleSheet(styles: Record<string, React.CSSProperties>) {\r\n if (typeof window === 'undefined') return defaultClassNames\r\n\r\n // Return early if styles are already injected\r\n if (styleInjection.isInjected) {\r\n return defaultClassNames\r\n }\r\n\r\n // Find existing style element or create new one\r\n let styleElement = document.querySelector<HTMLStyleElement>('[data-tern-secure]')\r\n \r\n if (!styleElement) {\r\n styleElement = document.createElement('style')\r\n styleElement.setAttribute('data-tern-secure', '')\r\n document.head.appendChild(styleElement)\r\n styleInjection.styleElement = styleElement\r\n }\r\n\r\n // Create CSS rules\r\n const cssRules = Object.entries(styles).map(([key, rules]) => {\r\n const className = defaultClassNames[key as keyof typeof defaultClassNames]\r\n const cssProperties = Object.entries(rules).map(([prop, value]) => {\r\n const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase()\r\n return `${cssProperty}: ${value};`\r\n }).join(' ')\r\n\r\n return `.${className} { ${cssProperties} }`\r\n }).join('\\n')\r\n\r\n // Insert styles only once\r\n styleElement.textContent = cssRules\r\n styleInjection.isInjected = true\r\n\r\n return defaultClassNames\r\n}\r\n\r\n// Style configuration\r\nexport const styleConfig = {\r\n container: {\r\n display: 'flex',\r\n minHeight: '100%',\r\n flex: '1',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '3rem 1.5rem'\r\n },\r\n header: {\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '28rem'\r\n },\r\n title: {\r\n marginTop: '1.5rem',\r\n textAlign: 'center',\r\n fontSize: '1.875rem',\r\n fontWeight: '700',\r\n lineHeight: '2.25rem',\r\n letterSpacing: '-0.025em',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n formWrapper: {\r\n marginTop: '2.5rem',\r\n margin: '0 auto',\r\n width: '100%',\r\n maxWidth: '30rem'\r\n },\r\n formContainer: {\r\n padding: '3rem 1.5rem',\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',\r\n borderRadius: '0.5rem',\r\n backgroundColor: 'var(--tern-background, white)'\r\n },\r\n form: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '1rem'\r\n },\r\n label: {\r\n display: 'block',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'var(--tern-text-secondary, #374151)'\r\n },\r\n input: {\r\n marginTop: '0.25rem',\r\n display: 'block',\r\n width: '100%',\r\n padding: '0.5rem 0.75rem',\r\n borderRadius: '0.375rem',\r\n border: '1px solid var(--tern-border, #D1D5DB)',\r\n backgroundColor: 'var(--tern-input-background, white)',\r\n color: 'var(--tern-text-primary, #111827)'\r\n },\r\n button: {\r\n display: 'flex',\r\n width: '100%',\r\n justifyContent: 'center',\r\n padding: '0.5rem 1rem',\r\n fontSize: '0.875rem',\r\n fontWeight: '500',\r\n color: 'white',\r\n backgroundColor: 'var(--tern-primary, #2563EB)',\r\n border: 'none',\r\n borderRadius: '0.375rem',\r\n cursor: 'pointer'\r\n },\r\n error: {\r\n color: 'var(--tern-error, #DC2626)',\r\n fontSize: '0.875rem'\r\n }\r\n} as const\r\n\r\n// Export pre-created styles\r\nexport const styles = createStyleSheet(styleConfig)\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": ["config", "auth", "jsx", "auth", "useState", "styles", "jsx", "useState"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tern-secure/nextjs",
3
- "version": "3.1.45",
3
+ "version": "3.1.46",
4
4
  "packageManager": "npm@10.9.0",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -97,7 +97,7 @@
97
97
  },
98
98
  "exports": {
99
99
  ".": {
100
- "types": "./dist/esm/index.d.ts",
100
+ "types": "./dist/esm/types.d.ts",
101
101
  "import": "./dist/esm/index.js",
102
102
  "require": "./dist/cjs/index.js"
103
103
  },
@@ -105,16 +105,6 @@
105
105
  "types": "./dist/esm/app-router/server/index.d.ts",
106
106
  "import": "./dist/esm/app-router/server/index.js",
107
107
  "require": "./dist/cjs/app-router/server/index.js"
108
- },
109
- "./client": {
110
- "types": "./dist/esm/app-router/client/index.d.ts",
111
- "import": "./dist/esm/app-router/client/index.js",
112
- "require": "./dist/cjs/app-router/client/index.js"
113
- },
114
- "./components": {
115
- "types": "./dist/esm/components/index.d.ts",
116
- "import": "./dist/esm/components/index.js",
117
- "require": "./dist/cjs/components/index.js"
118
108
  }
119
109
  },
120
110
  "engines": {
@@ -1,8 +0,0 @@
1
- "use client";
2
- import {
3
- TernSecureClientProvider
4
- } from "./chunk-Q7WUJODD.js";
5
- export {
6
- TernSecureClientProvider
7
- };
8
- //# sourceMappingURL=TernSecureProvider-7KNRQUY2.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,34 +0,0 @@
1
- // src/app-router/client/TernSecureProvider.tsx
2
- import React from "react";
3
-
4
- // src/boundary/TernSecureCtx.tsx
5
- import { createContext, useContext } from "react";
6
- var INTERNAL_CONTEXT_KEY = Symbol("TERN_SECURE_CONTEXT");
7
- var TernSecureContext = createContext(null);
8
- var useInternalContext = (hookName) => {
9
- const context = useContext(TernSecureContext);
10
- if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {
11
- throw new Error(
12
- `${hookName || "Hook"} must be used within TernSecureProvider. Please wrap your component with TernSecureProvider.`
13
- );
14
- }
15
- return context;
16
- };
17
-
18
- // src/app-router/client/TernSecureProvider.tsx
19
- import { jsx } from "react/jsx-runtime";
20
- function TernSecureClientProvider({ children }) {
21
- const contextValue = React.useMemo(
22
- () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),
23
- []
24
- );
25
- return /* @__PURE__ */ jsx(TernSecureContext.Provider, { value: contextValue, children });
26
- }
27
- TernSecureClientProvider.displayName = "TernSecureClientProvider";
28
-
29
- export {
30
- TernSecureContext,
31
- useInternalContext,
32
- TernSecureClientProvider
33
- };
34
- //# sourceMappingURL=chunk-Q7WUJODD.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/app-router/client/TernSecureProvider.tsx", "../../src/boundary/TernSecureCtx.tsx"],
4
- "sourcesContent": ["'use client'\r\n\r\nimport React from 'react'\r\nimport { INTERNAL_CONTEXT_KEY, TernSecureContext, TernSecureContextType } from '../../boundary/TernSecureCtx'\r\n\r\n/**\r\n * Props for the TernSecureClientProvider component\r\n */\r\ninterface TernSecureClientProviderProps {\r\n /** React child elements to be wrapped by the provider */\r\n children: React.ReactNode\r\n}\r\n\r\n/**\r\n * Provider component for TernSecure authentication\r\n * Must be used to wrap any components that use TernSecure hooks\r\n * \r\n * @example\r\n * ```tsx\r\n * function App() {\r\n * return (\r\n * <TernSecureClientProvider>\r\n * <YourApp />\r\n * </TernSecureClientProvider>\r\n * )\r\n * }\r\n * ```\r\n */\r\nexport function TernSecureClientProvider({ children }: TernSecureClientProviderProps): JSX.Element {\r\n // Memoize the context value to prevent unnecessary re-renders\r\n const contextValue = React.useMemo<TernSecureContextType>(\r\n () => ({ _contextKey: INTERNAL_CONTEXT_KEY }),\r\n []\r\n )\r\n\r\n return (\r\n <TernSecureContext.Provider value={contextValue}>\r\n {children}\r\n </TernSecureContext.Provider>\r\n )\r\n}\r\n\r\n// Add display name for better debugging\r\nTernSecureClientProvider.displayName = 'TernSecureClientProvider'", "'use client'\r\n\r\nimport { createContext, useContext } from 'react'\r\n\r\n/**\r\n * Internal context type for TernSecure authentication\r\n * @internal\r\n */\r\ninterface TernSecureContextType {\r\n readonly _contextKey: symbol\r\n}\r\n\r\n/**\r\n * Internal symbol used for context validation\r\n * @internal\r\n */\r\nconst INTERNAL_CONTEXT_KEY = Symbol('TERN_SECURE_CONTEXT')\r\n\r\n/**\r\n * Context for TernSecure authentication\r\n * @internal\r\n */\r\nconst TernSecureContext = createContext<TernSecureContextType | null>(null)\r\n\r\n/**\r\n * Hook to verify that components are rendered within the TernSecure provider\r\n * @param hookName - Name of the hook being used (for better error messages)\r\n * @throws {Error} When used outside of TernSecureProvider\r\n * @internal\r\n */\r\nconst useInternalContext = (hookName?: string): TernSecureContextType => {\r\n const context = useContext(TernSecureContext)\r\n \r\n if (!context || context._contextKey !== INTERNAL_CONTEXT_KEY) {\r\n throw new Error(\r\n `${hookName || 'Hook'} must be used within TernSecureProvider. ` +\r\n 'Please wrap your component with TernSecureProvider.'\r\n )\r\n }\r\n \r\n return context\r\n}\r\n\r\nexport {\r\n type TernSecureContextType,\r\n TernSecureContext,\r\n useInternalContext,\r\n INTERNAL_CONTEXT_KEY\r\n}"],
5
- "mappings": ";AAEA,OAAO,WAAW;;;ACAlB,SAAS,eAAe,kBAAkB;AAc1C,IAAM,uBAAuB,OAAO,qBAAqB;AAMzD,IAAM,oBAAoB,cAA4C,IAAI;AAQ1E,IAAM,qBAAqB,CAAC,aAA6C;AACvE,QAAM,UAAU,WAAW,iBAAiB;AAE5C,MAAI,CAAC,WAAW,QAAQ,gBAAgB,sBAAsB;AAC5D,UAAM,IAAI;AAAA,MACR,GAAG,YAAY,MAAM;AAAA,IAEvB;AAAA,EACF;AAEA,SAAO;AACT;;;ADLI;AARG,SAAS,yBAAyB,EAAE,SAAS,GAA+C;AAEjG,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO,EAAE,aAAa,qBAAqB;AAAA,IAC3C,CAAC;AAAA,EACH;AAEA,SACE,oBAAC,kBAAkB,UAAlB,EAA2B,OAAO,cAChC,UACH;AAEJ;AAGA,yBAAyB,cAAc;",
6
- "names": []
7
- }