@tern-secure/nextjs 3.0.5 → 3.0.6

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.
@@ -2,5 +2,5 @@ import React from 'react';
2
2
  interface TernSecureClientProps {
3
3
  children: React.ReactNode;
4
4
  }
5
- export declare function TernSecureClientProvider({ children }: TernSecureClientProps): React.JSX.Element;
5
+ export declare function TernSecureClientProvider({ children }: TernSecureClientProps): import("react/jsx-runtime").JSX.Element;
6
6
  export {};
@@ -2,5 +2,5 @@ import React, { ReactNode } from 'react';
2
2
  interface TernSecureProviderProps {
3
3
  children: ReactNode;
4
4
  }
5
- export declare function TernSecureProvider({ children }: TernSecureProviderProps): React.JSX.Element | (string | number | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode>)[] | null | undefined;
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;
6
6
  export {};
@@ -18,4 +18,4 @@ export interface SignInProps {
18
18
  label?: string;
19
19
  };
20
20
  }
21
- export declare function SignIn({ onSuccess, onError, redirectUrl, className, style, customStyles }: SignInProps): React.JSX.Element;
21
+ export declare function SignIn({ onSuccess, onError, redirectUrl, className, style, customStyles }: SignInProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ "use strict";var ae=Object.create;var P=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var ce=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty;var M=(e,r)=>()=>(e&&(r=e(e=0)),r);var O=(e,r)=>{for(var t in r)P(e,t,{get:r[t],enumerable:!0})},q=(e,r,t,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of le(r))!ue.call(e,n)&&n!==t&&P(e,n,{get:()=>r[n],enumerable:!(i=se(r,n))||i.enumerable});return e};var H=(e,r,t)=>(t=e!=null?ae(ce(e)):{},q(r||!e||!e.__esModule?P(t,"default",{value:e,enumerable:!0}):t,e)),me=e=>q(P({},"__esModule",{value:!0}),e);var $,fe,d,E,Y,F=M(()=>{"use strict";"use client";$=require("react"),fe=()=>(0,$.createContext)([{firebase:{initialized:!1,error:null},auth:{user:null,loading:!0,error:null,isSignedIn:!1}},()=>{}]),d=fe(),E=e=>{let r=(0,$.useContext)(d);if(!r)throw new Error(`${e} must be used within TernSecureProvider`);return r},Y={firebase:{initialized:!1,error:null},auth:{user:null,loading:!0,error:null,isSignedIn:!1}}});var Q={};O(Q,{TernSecureClientProvider:()=>y});function y({children:e}){let r=(0,Z.useState)(Y);return(0,ee.jsx)(d.Provider,{value:r,children:e})}var Z,ee,B=M(()=>{"use strict";"use client";Z=require("react");F();ee=require("react/jsx-runtime")});var he={};O(he,{SignIn:()=>j,TernSecureAuth:()=>u,TernSecureClientProvider:()=>y,TernSecureContext:()=>d,TernSecureFirestore:()=>_,TernSecureProvider:()=>D,TernSecureStorage:()=>w,loadFireConfig:()=>g,signInWithEmail:()=>h,useAuth:()=>U,useTernSecure:()=>E,validateConfig:()=>S});module.exports=me(he);var f=require("firebase/app"),m=require("firebase/auth"),G=require("firebase/firestore"),K=require("firebase/storage");var N=(()=>{let e=S(g());return(0,f.getApps)().length?(0,f.getApps)()[0]:(0,f.initializeApp)(e)})(),V=(0,m.getAuth)(N);(0,m.setPersistence)(V,m.browserSessionPersistence);var de=(0,G.getFirestore)(N),pe=(0,K.getStorage)(N),u=()=>V,_=()=>de,w=()=>pe;var J=require("firebase/auth");async function h({email:e,password:r}){let t=u();return(0,J.signInWithEmailAndPassword)(t,e,r)}var g=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY,authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID,measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID}),S=e=>(Object.entries(e).forEach(([r,t])=>{if(!t)throw new Error(`Missing environment variable: NEXT_PUBLIC_FIREBASE_${r.toUpperCase()}`)}),e);F();B();var c=H(require("react"),1),te=H(require("next/dynamic"),1),W=require("react/jsx-runtime"),re=(0,te.default)(()=>Promise.resolve().then(()=>(B(),Q)).then(e=>e.TernSecureClientProvider),{loading:()=>null});function D({children:e}){return c.default.Children.toArray(e).some(t=>c.default.isValidElement(t)&&t.type==="html")?c.default.Children.map(e,t=>c.default.isValidElement(t)&&t.type==="html"?c.default.cloneElement(t,{},c.default.Children.map(t.props.children,i=>{if(c.default.isValidElement(i)&&i.type==="body"){let n=i.props;return c.default.cloneElement(i,{},(0,W.jsx)(re,{children:n.children}))}return i})):t):(0,W.jsx)(re,{children:e})}var ne=require("react");function U(){let[e,r]=E("useAuth");return(0,ne.useEffect)(()=>{try{let t=u();r(n=>({...n,firebase:{initialized:!0,error:null}}));let i=t.onAuthStateChanged(n=>{r(o=>({...o,auth:{user:n,loading:!1,error:null,isSignedIn:!!n}}))},n=>{r(o=>({...o,auth:{user:null,loading:!1,error:n,isSignedIn:!1}}))});return()=>i()}catch(t){r(i=>({...i,firebase:{initialized:!1,error:t},auth:{user:null,loading:!1,error:t,isSignedIn:!1}}))}},[]),e.auth}var C=require("react");var l="tern",L={isInjected:!1,styleElement:null},A={container:`${l}-container`,header:`${l}-header`,title:`${l}-title`,formWrapper:`${l}-formWrapper`,formContainer:`${l}-formContainer`,form:`${l}-form`,label:`${l}-label`,input:`${l}-input`,button:`${l}-button`,error:`${l}-error`};function ge(e){if(typeof window>"u"||L.isInjected)return A;let r=document.querySelector("[data-tern-secure]");r||(r=document.createElement("style"),r.setAttribute("data-tern-secure",""),document.head.appendChild(r),L.styleElement=r);let t=Object.entries(e).map(([i,n])=>{let o=A[i],T=Object.entries(n).map(([R,v])=>`${R.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${v};`).join(" ");return`.${o} { ${T} }`}).join(`
2
+ `);return r.textContent=t,L.isInjected=!0,A}var Se={container:{display:"flex",minHeight:"100%",flex:"1",flexDirection:"column",justifyContent:"center",padding:"3rem 1.5rem"},header:{margin:"0 auto",width:"100%",maxWidth:"28rem"},title:{marginTop:"1.5rem",textAlign:"center",fontSize:"1.875rem",fontWeight:"700",lineHeight:"2.25rem",letterSpacing:"-0.025em",color:"var(--tern-text-primary, #111827)"},formWrapper:{marginTop:"2.5rem",margin:"0 auto",width:"100%",maxWidth:"30rem"},formContainer:{padding:"3rem 1.5rem",boxShadow:"0 1px 3px 0 rgb(0 0 0 / 0.1)",borderRadius:"0.5rem",backgroundColor:"var(--tern-background, white)"},form:{display:"flex",flexDirection:"column",gap:"1rem"},label:{display:"block",fontSize:"0.875rem",fontWeight:"500",color:"var(--tern-text-secondary, #374151)"},input:{marginTop:"0.25rem",display:"block",width:"100%",padding:"0.5rem 0.75rem",borderRadius:"0.375rem",border:"1px solid var(--tern-border, #D1D5DB)",backgroundColor:"var(--tern-input-background, white)",color:"var(--tern-text-primary, #111827)"},button:{display:"flex",width:"100%",justifyContent:"center",padding:"0.5rem 1rem",fontSize:"0.875rem",fontWeight:"500",color:"white",backgroundColor:"var(--tern-primary, #2563EB)",border:"none",borderRadius:"0.375rem",cursor:"pointer"},error:{color:"var(--tern-error, #DC2626)",fontSize:"0.875rem"}},s=ge(Se);var a=require("react/jsx-runtime");function j({onSuccess:e,onError:r,redirectUrl:t,className:i="",style:n,customStyles:o={}}){let[T,R]=(0,C.useState)(""),[v,k]=(0,C.useState)(""),[x,z]=(0,C.useState)(!1),[b,X]=(0,C.useState)(""),oe=async p=>{p.preventDefault(),z(!0),X("");try{await h({email:T,password:v}),e?.(),t&&(window.location.href=t)}catch(I){let ie=I instanceof Error?I.message:"Failed to sign in";X(ie),r?.(I instanceof Error?I:new Error("Failed to sign in"))}finally{z(!1)}};return(0,a.jsxs)("div",{className:`${s.container} ${o.container||""}`,style:n,children:[(0,a.jsx)("div",{className:`${s.header} ${o.header||""}`,children:(0,a.jsx)("h2",{className:`${s.title} ${o.title||""}`,children:"Sign in to your account"})}),(0,a.jsx)("div",{className:`${s.formWrapper} ${o.formWrapper||""}`,children:(0,a.jsx)("div",{className:`${s.formContainer} ${o.formContainer||""}`,children:(0,a.jsxs)("form",{onSubmit:oe,className:`${s.form} ${o.form||""} ${i}`,role:"form","aria-label":"Sign in form",children:[b&&(0,a.jsx)("div",{className:`${s.error} ${o.errorText||""}`,role:"alert","aria-live":"polite",children:b}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{htmlFor:"email",className:`${s.label} ${o.label||""}`,children:"Email"}),(0,a.jsx)("input",{id:"email",type:"email",value:T,onChange:p=>R(p.target.value),placeholder:"Enter your email",required:!0,className:`${s.input} ${o.input||""}`,disabled:x,"aria-required":"true","aria-invalid":!!b})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{htmlFor:"password",className:`${s.label} ${o.label||""}`,children:"Password"}),(0,a.jsx)("input",{id:"password",type:"password",value:v,onChange:p=>k(p.target.value),placeholder:"Enter your password",required:!0,className:`${s.input} ${o.input||""}`,disabled:x,"aria-required":"true","aria-invalid":!!b})]}),(0,a.jsx)("button",{type:"submit",disabled:x,className:`${s.button} ${o.button||""}`,"data-testid":"sign-in-submit",children:x?"Signing in...":"Sign in"})]})})})]})}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { TernSecureAuth, TernSecureFirestore, TernSecureStorage, signInWithEmail, loadFireConfig, validateConfig, TernSecureContext, useTernSecure, TernSecureClientProvider, SignInCredentials } from './app-router/client';
1
+ export { TernSecureAuth, TernSecureFirestore, TernSecureStorage, signInWithEmail, loadFireConfig, validateConfig, TernSecureContext, useTernSecure, TernSecureClientProvider } from './app-router/client';
2
2
  export { TernSecureProvider } from './app-router/server';
3
3
  export { useAuth } from './hooks';
4
4
  export { SignIn } from './components';
package/dist/index.js CHANGED
@@ -1,342 +1,2 @@
1
- import { getApps, initializeApp } from 'firebase/app';
2
- import { getAuth, setPersistence, browserSessionPersistence, signInWithEmailAndPassword } from 'firebase/auth';
3
- import { getFirestore } from 'firebase/firestore';
4
- import { getStorage } from 'firebase/storage';
5
- import * as React from 'react';
6
- import React__default, { createContext, useContext, useState, useEffect } from 'react';
7
- import dynamic from 'next/dynamic';
8
-
9
- // Initialize immediately
10
- const app = (() => {
11
- const config = validateConfig(loadFireConfig());
12
- return getApps().length ? getApps()[0] : initializeApp(config);
13
- })();
14
- const auth = getAuth(app);
15
- setPersistence(auth, browserSessionPersistence); //to change later user should be able to choose persistance
16
- const firestore = getFirestore(app);
17
- const storage = getStorage(app);
18
- const TernSecureAuth = () => auth;
19
- const TernSecureFirestore = () => firestore;
20
- const TernSecureStorage = () => storage;
21
-
22
- async function signInWithEmail({ email, password }) {
23
- const auth = TernSecureAuth();
24
- return signInWithEmailAndPassword(auth, email, password);
25
- }
26
-
27
- const loadFireConfig = () => ({
28
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
29
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
30
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
31
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
32
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
33
- appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
34
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
35
- });
36
- const validateConfig = (config) => {
37
- Object.entries(config).forEach(([key, value]) => {
38
- if (!value) {
39
- throw new Error(`Missing environment variable: NEXT_PUBLIC_FIREBASE_${key.toUpperCase()}`);
40
- }
41
- });
42
- return config;
43
- };
44
-
45
- const createTernSecureContext = () => {
46
- const initialState = {
47
- firebase: {
48
- initialized: false,
49
- error: null
50
- },
51
- auth: {
52
- user: null,
53
- loading: true,
54
- error: null,
55
- isSignedIn: false
56
- }
57
- };
58
- return createContext([initialState, () => { }]);
59
- };
60
- // Create context instance only when imported on client
61
- const TernSecureContext = createTernSecureContext();
62
- const useTernSecure = (hookname) => {
63
- const context = useContext(TernSecureContext);
64
- if (!context) {
65
- throw new Error(`${hookname} must be used within TernSecureProvider`);
66
- }
67
- return context;
68
- };
69
- // Export initial state for reuse
70
- const initialState = {
71
- firebase: {
72
- initialized: false,
73
- error: null
74
- },
75
- auth: {
76
- user: null,
77
- loading: true,
78
- error: null,
79
- isSignedIn: false
80
- }
81
- };
82
-
83
- function TernSecureClientProvider$1({ children }) {
84
- const stateAndUpdater = useState(initialState);
85
- return (React__default.createElement(TernSecureContext.Provider, { value: stateAndUpdater }, children));
86
- }
87
-
88
- var ternSecureClientProvider = /*#__PURE__*/Object.freeze({
89
- __proto__: null,
90
- TernSecureClientProvider: TernSecureClientProvider$1
91
- });
92
-
93
- // Dynamically import the client provider with no SSR
94
- const TernSecureClientProvider = dynamic(() => Promise.resolve().then(function () { return ternSecureClientProvider; }).then(mod => mod.TernSecureClientProvider), {
95
- //ssr: false,
96
- loading: () => null // Return null or a loading indicator
97
- });
98
- function TernSecureProvider({ children }) {
99
- // Check if the children contain html/body tags
100
- const isRootLayout = React__default.Children.toArray(children).some(child => React__default.isValidElement(child) && child.type === 'html');
101
- if (isRootLayout) {
102
- // If this is the root layout, inject our provider after the body tag
103
- return React__default.Children.map(children, child => {
104
- if (React__default.isValidElement(child) && child.type === 'html') {
105
- return React__default.cloneElement(child, {}, React__default.Children.map(child.props.children, bodyChild => {
106
- if (React__default.isValidElement(bodyChild) && bodyChild.type === 'body') {
107
- // Type assertion to access props safely
108
- const bodyProps = bodyChild.props;
109
- return React__default.cloneElement(bodyChild, {}, React__default.createElement(TernSecureClientProvider, null, bodyProps.children));
110
- }
111
- return bodyChild;
112
- }));
113
- }
114
- return child;
115
- });
116
- }
117
- // For non-root layouts, wrap normally
118
- return React__default.createElement(TernSecureClientProvider, null, children);
119
- }
120
-
121
- function useAuth() {
122
- const [state, setState] = useTernSecure('useAuth');
123
- useEffect(() => {
124
- try {
125
- const auth = TernSecureAuth(); // This initializes Firebase
126
- setState(prev => ({
127
- ...prev,
128
- firebase: {
129
- initialized: true,
130
- error: null
131
- }
132
- }));
133
- const unsubscribe = auth.onAuthStateChanged((user) => {
134
- setState(prev => ({
135
- ...prev,
136
- auth: {
137
- user,
138
- loading: false,
139
- error: null,
140
- isSignedIn: !!user
141
- }
142
- }));
143
- }, (error) => {
144
- setState(prev => ({
145
- ...prev,
146
- auth: {
147
- user: null,
148
- loading: false,
149
- error,
150
- isSignedIn: false
151
- }
152
- }));
153
- });
154
- return () => unsubscribe();
155
- }
156
- catch (error) {
157
- setState(prev => ({
158
- ...prev,
159
- firebase: {
160
- initialized: false,
161
- error: error
162
- },
163
- auth: {
164
- user: null,
165
- loading: false,
166
- error: error,
167
- isSignedIn: false
168
- }
169
- }));
170
- }
171
- }, []); // Only run once on mount
172
- return state.auth;
173
- }
174
-
175
- const PREFIX = 'tern';
176
- // Singleton to track style injection
177
- const styleInjection = {
178
- isInjected: false,
179
- styleElement: null
180
- };
181
- const defaultClassNames = {
182
- container: `${PREFIX}-container`,
183
- header: `${PREFIX}-header`,
184
- title: `${PREFIX}-title`,
185
- formWrapper: `${PREFIX}-formWrapper`,
186
- formContainer: `${PREFIX}-formContainer`,
187
- form: `${PREFIX}-form`,
188
- label: `${PREFIX}-label`,
189
- input: `${PREFIX}-input`,
190
- button: `${PREFIX}-button`,
191
- error: `${PREFIX}-error`
192
- };
193
- // Create styles once and cache them
194
- function createStyleSheet(styles) {
195
- if (typeof window === 'undefined')
196
- return defaultClassNames;
197
- // Return early if styles are already injected
198
- if (styleInjection.isInjected) {
199
- return defaultClassNames;
200
- }
201
- // Find existing style element or create new one
202
- let styleElement = document.querySelector('[data-tern-secure]');
203
- if (!styleElement) {
204
- styleElement = document.createElement('style');
205
- styleElement.setAttribute('data-tern-secure', '');
206
- document.head.appendChild(styleElement);
207
- styleInjection.styleElement = styleElement;
208
- }
209
- // Create CSS rules
210
- const cssRules = Object.entries(styles).map(([key, rules]) => {
211
- const className = defaultClassNames[key];
212
- const cssProperties = Object.entries(rules).map(([prop, value]) => {
213
- const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
214
- return `${cssProperty}: ${value};`;
215
- }).join(' ');
216
- return `.${className} { ${cssProperties} }`;
217
- }).join('\n');
218
- // Insert styles only once
219
- styleElement.textContent = cssRules;
220
- styleInjection.isInjected = true;
221
- return defaultClassNames;
222
- }
223
- // Style configuration
224
- const styleConfig = {
225
- container: {
226
- display: 'flex',
227
- minHeight: '100%',
228
- flex: '1',
229
- flexDirection: 'column',
230
- justifyContent: 'center',
231
- padding: '3rem 1.5rem'
232
- },
233
- header: {
234
- margin: '0 auto',
235
- width: '100%',
236
- maxWidth: '28rem'
237
- },
238
- title: {
239
- marginTop: '1.5rem',
240
- textAlign: 'center',
241
- fontSize: '1.875rem',
242
- fontWeight: '700',
243
- lineHeight: '2.25rem',
244
- letterSpacing: '-0.025em',
245
- color: 'var(--tern-text-primary, #111827)'
246
- },
247
- formWrapper: {
248
- marginTop: '2.5rem',
249
- margin: '0 auto',
250
- width: '100%',
251
- maxWidth: '30rem'
252
- },
253
- formContainer: {
254
- padding: '3rem 1.5rem',
255
- boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',
256
- borderRadius: '0.5rem',
257
- backgroundColor: 'var(--tern-background, white)'
258
- },
259
- form: {
260
- display: 'flex',
261
- flexDirection: 'column',
262
- gap: '1rem'
263
- },
264
- label: {
265
- display: 'block',
266
- fontSize: '0.875rem',
267
- fontWeight: '500',
268
- color: 'var(--tern-text-secondary, #374151)'
269
- },
270
- input: {
271
- marginTop: '0.25rem',
272
- display: 'block',
273
- width: '100%',
274
- padding: '0.5rem 0.75rem',
275
- borderRadius: '0.375rem',
276
- border: '1px solid var(--tern-border, #D1D5DB)',
277
- backgroundColor: 'var(--tern-input-background, white)',
278
- color: 'var(--tern-text-primary, #111827)'
279
- },
280
- button: {
281
- display: 'flex',
282
- width: '100%',
283
- justifyContent: 'center',
284
- padding: '0.5rem 1rem',
285
- fontSize: '0.875rem',
286
- fontWeight: '500',
287
- color: 'white',
288
- backgroundColor: 'var(--tern-primary, #2563EB)',
289
- border: 'none',
290
- borderRadius: '0.375rem',
291
- cursor: 'pointer'
292
- },
293
- error: {
294
- color: 'var(--tern-error, #DC2626)',
295
- fontSize: '0.875rem'
296
- }
297
- };
298
- // Export pre-created styles
299
- const styles = createStyleSheet(styleConfig);
300
-
301
- function SignIn({ onSuccess, onError, redirectUrl, className = '', style, customStyles = {} }) {
302
- const [email, setEmail] = useState('');
303
- const [password, setPassword] = useState('');
304
- const [loading, setLoading] = useState(false);
305
- const [error, setError] = useState('');
306
- const handleSubmit = async (e) => {
307
- e.preventDefault();
308
- setLoading(true);
309
- setError('');
310
- try {
311
- await signInWithEmail({ email, password });
312
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
313
- if (redirectUrl) {
314
- window.location.href = redirectUrl;
315
- }
316
- }
317
- catch (err) {
318
- const errorMessage = err instanceof Error ? err.message : 'Failed to sign in';
319
- setError(errorMessage);
320
- onError === null || onError === void 0 ? void 0 : onError(err instanceof Error ? err : new Error('Failed to sign in'));
321
- }
322
- finally {
323
- setLoading(false);
324
- }
325
- };
326
- return (React.createElement("div", { className: `${styles.container} ${customStyles.container || ''}`, style: style },
327
- React.createElement("div", { className: `${styles.header} ${customStyles.header || ''}` },
328
- React.createElement("h2", { className: `${styles.title} ${customStyles.title || ''}` }, "Sign in to your account")),
329
- React.createElement("div", { className: `${styles.formWrapper} ${customStyles.formWrapper || ''}` },
330
- React.createElement("div", { className: `${styles.formContainer} ${customStyles.formContainer || ''}` },
331
- React.createElement("form", { onSubmit: handleSubmit, className: `${styles.form} ${customStyles.form || ''} ${className}`, role: "form", "aria-label": "Sign in form" },
332
- error && (React.createElement("div", { className: `${styles.error} ${customStyles.errorText || ''}`, role: "alert", "aria-live": "polite" }, error)),
333
- React.createElement("div", null,
334
- React.createElement("label", { htmlFor: "email", className: `${styles.label} ${customStyles.label || ''}` }, "Email"),
335
- React.createElement("input", { id: "email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "Enter your email", required: true, className: `${styles.input} ${customStyles.input || ''}`, disabled: loading, "aria-required": "true", "aria-invalid": !!error })),
336
- React.createElement("div", null,
337
- React.createElement("label", { htmlFor: "password", className: `${styles.label} ${customStyles.label || ''}` }, "Password"),
338
- React.createElement("input", { id: "password", type: "password", value: password, onChange: (e) => setPassword(e.target.value), placeholder: "Enter your password", required: true, className: `${styles.input} ${customStyles.input || ''}`, disabled: loading, "aria-required": "true", "aria-invalid": !!error })),
339
- React.createElement("button", { type: "submit", disabled: loading, className: `${styles.button} ${customStyles.button || ''}`, "data-testid": "sign-in-submit" }, loading ? 'Signing in...' : 'Sign in'))))));
340
- }
341
-
342
- export { SignIn, TernSecureAuth, TernSecureClientProvider$1 as TernSecureClientProvider, TernSecureContext, TernSecureFirestore, TernSecureProvider, TernSecureStorage, loadFireConfig, signInWithEmail, useAuth, useTernSecure, validateConfig };
1
+ var K=Object.defineProperty;var B=(e,r)=>()=>(e&&(r=e(e=0)),r);var V=(e,r)=>{for(var t in r)K(e,t,{get:r[t],enumerable:!0})};import{createContext as ie,useContext as ae}from"react";var se,d,v,j,y=B(()=>{"use strict";"use client";se=()=>ie([{firebase:{initialized:!1,error:null},auth:{user:null,loading:!0,error:null,isSignedIn:!1}},()=>{}]),d=se(),v=e=>{let r=ae(d);if(!r)throw new Error(`${e} must be used within TernSecureProvider`);return r},j={firebase:{initialized:!1,error:null},auth:{user:null,loading:!0,error:null,isSignedIn:!1}}});var k={};V(k,{TernSecureClientProvider:()=>A});import{useState as le}from"react";import{jsx as ce}from"react/jsx-runtime";function A({children:e}){let r=le(j);return ce(d.Provider,{value:r,children:e})}var R=B(()=>{"use strict";"use client";y()});import{getApps as W,initializeApp as J}from"firebase/app";import{getAuth as Y,setPersistence as Z,browserSessionPersistence as Q}from"firebase/auth";import{getFirestore as ee}from"firebase/firestore";import{getStorage as re}from"firebase/storage";var $=(()=>{let e=C(E());return W().length?W()[0]:J(e)})(),D=Y($);Z(D,Q);var te=ee($),ne=re($),u=()=>D,U=()=>te,L=()=>ne;import{signInWithEmailAndPassword as oe}from"firebase/auth";async function T({email:e,password:r}){let t=u();return oe(t,e,r)}var E=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY,authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID,measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID}),C=e=>(Object.entries(e).forEach(([r,t])=>{if(!t)throw new Error(`Missing environment variable: NEXT_PUBLIC_FIREBASE_${r.toUpperCase()}`)}),e);y();R();import c from"react";import ue from"next/dynamic";import{jsx as X}from"react/jsx-runtime";var z=ue(()=>Promise.resolve().then(()=>(R(),k)).then(e=>e.TernSecureClientProvider),{loading:()=>null});function M({children:e}){return c.Children.toArray(e).some(t=>c.isValidElement(t)&&t.type==="html")?c.Children.map(e,t=>c.isValidElement(t)&&t.type==="html"?c.cloneElement(t,{},c.Children.map(t.props.children,o=>{if(c.isValidElement(o)&&o.type==="body"){let a=o.props;return c.cloneElement(o,{},X(z,{children:a.children}))}return o})):t):X(z,{children:e})}import{useEffect as me}from"react";function O(){let[e,r]=v("useAuth");return me(()=>{try{let t=u();r(a=>({...a,firebase:{initialized:!0,error:null}}));let o=t.onAuthStateChanged(a=>{r(n=>({...n,auth:{user:a,loading:!1,error:null,isSignedIn:!!a}}))},a=>{r(n=>({...n,auth:{user:null,loading:!1,error:a,isSignedIn:!1}}))});return()=>o()}catch(t){r(o=>({...o,firebase:{initialized:!1,error:t},auth:{user:null,loading:!1,error:t,isSignedIn:!1}}))}},[]),e.auth}import{useState as b}from"react";var s="tern",N={isInjected:!1,styleElement:null},x={container:`${s}-container`,header:`${s}-header`,title:`${s}-title`,formWrapper:`${s}-formWrapper`,formContainer:`${s}-formContainer`,form:`${s}-form`,label:`${s}-label`,input:`${s}-input`,button:`${s}-button`,error:`${s}-error`};function de(e){if(typeof window>"u"||N.isInjected)return x;let r=document.querySelector("[data-tern-secure]");r||(r=document.createElement("style"),r.setAttribute("data-tern-secure",""),document.head.appendChild(r),N.styleElement=r);let t=Object.entries(e).map(([o,a])=>{let n=x[o],p=Object.entries(a).map(([P,f])=>`${P.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${f};`).join(" ");return`.${n} { ${p} }`}).join(`
2
+ `);return r.textContent=t,N.isInjected=!0,x}var pe={container:{display:"flex",minHeight:"100%",flex:"1",flexDirection:"column",justifyContent:"center",padding:"3rem 1.5rem"},header:{margin:"0 auto",width:"100%",maxWidth:"28rem"},title:{marginTop:"1.5rem",textAlign:"center",fontSize:"1.875rem",fontWeight:"700",lineHeight:"2.25rem",letterSpacing:"-0.025em",color:"var(--tern-text-primary, #111827)"},formWrapper:{marginTop:"2.5rem",margin:"0 auto",width:"100%",maxWidth:"30rem"},formContainer:{padding:"3rem 1.5rem",boxShadow:"0 1px 3px 0 rgb(0 0 0 / 0.1)",borderRadius:"0.5rem",backgroundColor:"var(--tern-background, white)"},form:{display:"flex",flexDirection:"column",gap:"1rem"},label:{display:"block",fontSize:"0.875rem",fontWeight:"500",color:"var(--tern-text-secondary, #374151)"},input:{marginTop:"0.25rem",display:"block",width:"100%",padding:"0.5rem 0.75rem",borderRadius:"0.375rem",border:"1px solid var(--tern-border, #D1D5DB)",backgroundColor:"var(--tern-input-background, white)",color:"var(--tern-text-primary, #111827)"},button:{display:"flex",width:"100%",justifyContent:"center",padding:"0.5rem 1rem",fontSize:"0.875rem",fontWeight:"500",color:"white",backgroundColor:"var(--tern-primary, #2563EB)",border:"none",borderRadius:"0.375rem",cursor:"pointer"},error:{color:"var(--tern-error, #DC2626)",fontSize:"0.875rem"}},i=de(pe);import{jsx as l,jsxs as I}from"react/jsx-runtime";function q({onSuccess:e,onError:r,redirectUrl:t,className:o="",style:a,customStyles:n={}}){let[p,P]=b(""),[f,_]=b(""),[g,w]=b(!1),[S,F]=b(""),H=async m=>{m.preventDefault(),w(!0),F("");try{await T({email:p,password:f}),e?.(),t&&(window.location.href=t)}catch(h){let G=h instanceof Error?h.message:"Failed to sign in";F(G),r?.(h instanceof Error?h:new Error("Failed to sign in"))}finally{w(!1)}};return I("div",{className:`${i.container} ${n.container||""}`,style:a,children:[l("div",{className:`${i.header} ${n.header||""}`,children:l("h2",{className:`${i.title} ${n.title||""}`,children:"Sign in to your account"})}),l("div",{className:`${i.formWrapper} ${n.formWrapper||""}`,children:l("div",{className:`${i.formContainer} ${n.formContainer||""}`,children:I("form",{onSubmit:H,className:`${i.form} ${n.form||""} ${o}`,role:"form","aria-label":"Sign in form",children:[S&&l("div",{className:`${i.error} ${n.errorText||""}`,role:"alert","aria-live":"polite",children:S}),I("div",{children:[l("label",{htmlFor:"email",className:`${i.label} ${n.label||""}`,children:"Email"}),l("input",{id:"email",type:"email",value:p,onChange:m=>P(m.target.value),placeholder:"Enter your email",required:!0,className:`${i.input} ${n.input||""}`,disabled:g,"aria-required":"true","aria-invalid":!!S})]}),I("div",{children:[l("label",{htmlFor:"password",className:`${i.label} ${n.label||""}`,children:"Password"}),l("input",{id:"password",type:"password",value:f,onChange:m=>_(m.target.value),placeholder:"Enter your password",required:!0,className:`${i.input} ${n.input||""}`,disabled:g,"aria-required":"true","aria-invalid":!!S})]}),l("button",{type:"submit",disabled:g,className:`${i.button} ${n.button||""}`,"data-testid":"sign-in-submit",children:g?"Signing in...":"Sign in"})]})})})]})}export{q as SignIn,u as TernSecureAuth,A as TernSecureClientProvider,d as TernSecureContext,U as TernSecureFirestore,M as TernSecureProvider,L as TernSecureStorage,E as loadFireConfig,T as signInWithEmail,O as useAuth,v as useTernSecure,C as validateConfig};
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@tern-secure/nextjs",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
+ "type": "module",
4
5
  "publishConfig": {
5
6
  "access": "public",
6
7
  "registry": "https://registry.npmjs.org/"
@@ -13,14 +14,17 @@
13
14
  "url": "https://github.com/TernSecure/nextjs/issues"
14
15
  },
15
16
  "homepage": "https://github.com/tern-secure/nextjs#readme",
16
- "main": "./dist/index.js",
17
+ "main": "./dist/index.cjs.js",
17
18
  "module": "./dist/index.js",
18
- "scripts": {
19
- "build": "rollup -c",
20
- "clean": "rimraf dist",
21
- "dev": "tsc --watch",
19
+ "scripts": {
20
+ "build": "npm run build:types && npm run build:js",
21
+ "build:types": "tsc --emitDeclarationOnly",
22
+ "build:js": "node build.config.cjs",
23
+ "clean": "rimraf dist",
24
+ "dev": "npm run build -- --watch",
22
25
  "lint": "eslint \"src/**/*.{ts,tsx}\"",
23
- "format": "prettier --write \"src/**/*.{ts,tsx}\""
26
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
27
+ "prepublishOnly": "npm run build"
24
28
  },
25
29
  "keywords": [],
26
30
  "author": "",
@@ -42,6 +46,8 @@
42
46
  "@typescript-eslint/eslint-plugin": "^8.15.0",
43
47
  "@typescript-eslint/parser": "^8.15.0",
44
48
  "autoprefixer": "^10.4.20",
49
+ "esbuild": "^0.24.0",
50
+ "esbuild-node-externals": "^1.15.0",
45
51
  "eslint": "^9.15.0",
46
52
  "eslint-plugin-react": "^7.37.2",
47
53
  "firebase": "^11.0.2",
@@ -86,17 +92,16 @@
86
92
  "optional": true
87
93
  }
88
94
  },
89
- "exports": {
95
+ "exports": {
90
96
  ".": {
91
97
  "types": "./dist/index.d.ts",
92
98
  "import": "./dist/index.js",
93
- "require": "./dist/index.js"
99
+ "require": "./dist/index.cjs.js"
94
100
  },
95
101
  "./server": {
96
102
  "types": "./dist/server/index.d.ts",
97
103
  "import": "./dist/server/index.js",
98
- "require": "./dist/server/index.js"
99
- },
100
- "./styles": "./styles/index.css"
104
+ "require": "./dist/server/index.cjs.js"
105
+ }
101
106
  }
102
107
  }