@proveanything/smartlinks 1.0.50 → 1.0.52

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/API_SUMMARY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.0.50 | Generated: 2025-11-23T11:52:15.257Z
3
+ Version: 1.0.52 | Generated: 2025-11-24T19:18:29.127Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -37,6 +37,7 @@ Core HTTP functions for API configuration and communication:
37
37
  proxyMode?: boolean
38
38
  ngrokSkipBrowserWarning?: boolean
39
39
  extraHeaders?: Record<string, string>
40
+ iframeAutoResize?: boolean // default true when in iframe
40
41
  }) → `void`
41
42
  Call this once (e.g. at app startup) to configure baseURL/auth.
42
43
 
@@ -161,6 +162,37 @@ interface AuthKitUser {
161
162
  }
162
163
  ```
163
164
 
165
+ **UserProfile** (interface)
166
+ ```typescript
167
+ interface UserProfile {
168
+ uid: string
169
+ email?: string
170
+ displayName?: string | null
171
+ phoneNumber?: string | null
172
+ photoURL?: string | null
173
+ emailVerified?: boolean
174
+ accountData?: Record<string, any>
175
+ }
176
+ ```
177
+
178
+ **ProfileUpdateData** (interface)
179
+ ```typescript
180
+ interface ProfileUpdateData {
181
+ displayName?: string
182
+ photoURL?: string
183
+ accountData?: Record<string, any>
184
+ }
185
+ ```
186
+
187
+ **SuccessResponse** (interface)
188
+ ```typescript
189
+ interface SuccessResponse {
190
+ success: boolean
191
+ message?: string
192
+ token?: string // some flows may return a refreshed token
193
+ }
194
+ ```
195
+
164
196
  **AuthLoginResponse** (interface)
165
197
  ```typescript
166
198
  interface AuthLoginResponse {
@@ -822,6 +854,27 @@ Verify phone verification code (public).
822
854
  **resendEmailVerification**(clientId: string, data: { userId: string; email: string; redirectUrl?: string; clientName?: string }) → `Promise<EmailVerificationActionResponse>`
823
855
  Verify phone verification code (public).
824
856
 
857
+ **getProfile**(clientId: string) → `Promise<UserProfile>`
858
+ Verify phone verification code (public).
859
+
860
+ **updateProfile**(clientId: string, data: ProfileUpdateData) → `Promise<UserProfile>`
861
+ Verify phone verification code (public).
862
+
863
+ **changePassword**(clientId: string, currentPassword: string, newPassword: string) → `Promise<SuccessResponse>`
864
+ Verify phone verification code (public).
865
+
866
+ **changeEmail**(clientId: string, newEmail: string, password: string, redirectUrl: string) → `Promise<SuccessResponse>`
867
+ Verify phone verification code (public).
868
+
869
+ **verifyEmailChange**(clientId: string, token: string) → `Promise<SuccessResponse>`
870
+ Verify phone verification code (public).
871
+
872
+ **updatePhone**(clientId: string, phoneNumber: string, verificationCode: string) → `Promise<SuccessResponse>`
873
+ Verify phone verification code (public).
874
+
875
+ **deleteAccount**(clientId: string, password: string, confirmText: string) → `Promise<SuccessResponse>`
876
+ Verify phone verification code (public).
877
+
825
878
  **load**(authKitId: string) → `Promise<AuthKitConfig>`
826
879
  Verify phone verification code (public).
827
880
 
package/README.md CHANGED
@@ -141,6 +141,58 @@ const collections = await collection.list(false)
141
141
 
142
142
  For a fuller UI example, see `examples/react-demo.tsx`.
143
143
 
144
+ ## Iframe Integration
145
+
146
+ When embedding Smartlinks inside an iframe (set `proxyMode: true` in `initializeApi` if you need parent-proxy API calls), you can also send UI/control messages to the parent window. The SDK provides lightweight helpers in `iframe.ts`:
147
+
148
+ ```ts
149
+ import { enableAutoIframeResize, disableAutoIframeResize, redirectParent, sendParentCustom, isIframe } from '@proveanything/smartlinks'
150
+
151
+ // Automatically push height changes to parent so it can resize the iframe.
152
+ enableAutoIframeResize({ intervalMs: 150 })
153
+
154
+ // Later disable if not needed:
155
+ disableAutoIframeResize()
156
+
157
+ // Redirect parent window to a URL (e.g. after login):
158
+ redirectParent('https://app.example.com/dashboard')
159
+
160
+ // Send any custom event + payload:
161
+ sendParentCustom('smartlinks:navigate', { url: '/profile' })
162
+
163
+ if (isIframe()) {
164
+ console.log('Running inside an iframe')
165
+ }
166
+ ```
167
+
168
+ Parent page can listen for these messages:
169
+
170
+ ```ts
171
+ window.addEventListener('message', (e) => {
172
+ const msg = e.data
173
+ if (!msg || !msg._smartlinksIframeMessage) return
174
+ switch (msg.type) {
175
+ case 'smartlinks:resize':
176
+ // adjust iframe height
177
+ const iframeEl = document.getElementById('smartlinks-frame') as HTMLIFrameElement
178
+ if (iframeEl) iframeEl.style.height = msg.payload.height + 'px'
179
+ break
180
+ case 'smartlinks:redirect':
181
+ window.location.href = msg.payload.url
182
+ break
183
+ case 'smartlinks:navigate':
184
+ // Custom example
185
+ console.log('Navigate request:', msg.payload.url)
186
+ break
187
+ }
188
+ })
189
+ ```
190
+
191
+ Notes:
192
+ - Auto-resize uses `ResizeObserver` when available, falling back to `MutationObserver` + polling.
193
+ - In non-browser or Node environments these helpers safely no-op.
194
+ - Use `sendParentCustom` for any domain-specific integration events.
195
+
144
196
  ## Configuration reference
145
197
 
146
198
  ```ts
@@ -151,10 +203,12 @@ initializeApi({
151
203
  proxyMode?: boolean // set true if running inside an iframe and using parent proxy
152
204
  ngrokSkipBrowserWarning?: boolean // forces header 'ngrok-skip-browser-warning: true'
153
205
  extraHeaders?: Record<string,string> // custom headers merged in each request
206
+ iframeAutoResize?: boolean // default true when embedded in an iframe
154
207
  })
155
208
 
156
209
  // Auto-detection: If baseURL contains '.ngrok.io' or '.ngrok-free.dev' the header is added automatically
157
210
  // unless you explicitly set ngrokSkipBrowserWarning: false.
211
+ // Auto iframe resize: When in an iframe, resize messages are sent by default unless iframeAutoResize: false.
158
212
  ```
159
213
 
160
214
  When embedding the SDK in an iframe with `proxyMode: true`, you can also use:
@@ -1,4 +1,4 @@
1
- import type { AuthLoginResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse } from "../types/authKit";
1
+ import type { AuthLoginResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, ProfileUpdateData, SuccessResponse } from "../types/authKit";
2
2
  /**
3
3
  * Namespace containing helper functions for the new AuthKit API.
4
4
  * Legacy collection-based authKit helpers retained (marked as *Legacy*).
@@ -47,6 +47,13 @@ export declare namespace authKit {
47
47
  redirectUrl?: string;
48
48
  clientName?: string;
49
49
  }): Promise<EmailVerificationActionResponse>;
50
+ function getProfile(clientId: string): Promise<UserProfile>;
51
+ function updateProfile(clientId: string, data: ProfileUpdateData): Promise<UserProfile>;
52
+ function changePassword(clientId: string, currentPassword: string, newPassword: string): Promise<SuccessResponse>;
53
+ function changeEmail(clientId: string, newEmail: string, password: string, redirectUrl: string): Promise<SuccessResponse>;
54
+ function verifyEmailChange(clientId: string, token: string): Promise<SuccessResponse>;
55
+ function updatePhone(clientId: string, phoneNumber: string, verificationCode: string): Promise<SuccessResponse>;
56
+ function deleteAccount(clientId: string, password: string, confirmText: string): Promise<SuccessResponse>;
50
57
  function load(authKitId: string): Promise<AuthKitConfig>;
51
58
  function get(collectionId: string, authKitId: string): Promise<AuthKitConfig>;
52
59
  function list(collectionId: string, admin?: boolean): Promise<AuthKitConfig[]>;
@@ -76,6 +76,43 @@ export var authKit;
76
76
  return post(`/authkit/${encodeURIComponent(clientId)}/auth/resend-verification`, data);
77
77
  }
78
78
  authKit.resendEmailVerification = resendEmailVerification;
79
+ /* ===================================
80
+ * Account Management (Authenticated)
81
+ * =================================== */
82
+ async function getProfile(clientId) {
83
+ return request(`/authkit/${encodeURIComponent(clientId)}/account/profile`);
84
+ }
85
+ authKit.getProfile = getProfile;
86
+ async function updateProfile(clientId, data) {
87
+ return post(`/authkit/${encodeURIComponent(clientId)}/account/update-profile`, data);
88
+ }
89
+ authKit.updateProfile = updateProfile;
90
+ async function changePassword(clientId, currentPassword, newPassword) {
91
+ return post(`/authkit/${encodeURIComponent(clientId)}/account/change-password`, { currentPassword, newPassword });
92
+ }
93
+ authKit.changePassword = changePassword;
94
+ async function changeEmail(clientId, newEmail, password, redirectUrl) {
95
+ return post(`/authkit/${encodeURIComponent(clientId)}/account/change-email`, { newEmail, password, redirectUrl });
96
+ }
97
+ authKit.changeEmail = changeEmail;
98
+ async function verifyEmailChange(clientId, token) {
99
+ const res = await post(`/authkit/${encodeURIComponent(clientId)}/account/verify-email-change`, { token });
100
+ if (res.token)
101
+ setBearerToken(res.token);
102
+ return res;
103
+ }
104
+ authKit.verifyEmailChange = verifyEmailChange;
105
+ async function updatePhone(clientId, phoneNumber, verificationCode) {
106
+ return post(`/authkit/${encodeURIComponent(clientId)}/account/update-phone`, { phoneNumber, verificationCode });
107
+ }
108
+ authKit.updatePhone = updatePhone;
109
+ async function deleteAccount(clientId, password, confirmText) {
110
+ // DELETE with body using requestWithOptions since del() doesn't send body
111
+ const path = `/authkit/${encodeURIComponent(clientId)}/account/delete`;
112
+ const res = await post(path, { password, confirmText }); // If backend truly requires DELETE, switch to requestWithOptions
113
+ return res;
114
+ }
115
+ authKit.deleteAccount = deleteAccount;
79
116
  /* ===================================
80
117
  * Collection-based AuthKit
81
118
  * =================================== */
package/dist/http.d.ts CHANGED
@@ -1,12 +1,3 @@
1
- /**
2
- * Call this once (e.g. at app startup) to configure baseURL/auth.
3
- *
4
- * @param options - Configuration options
5
- * @property {string} options.baseURL - The root URL of the Smartlinks API (e.g. "https://smartlinks.app/api/v1")
6
- * @property {string} [options.apiKey] - (Optional) API key for X-API-Key header
7
- * @property {string} [options.bearerToken] - (Optional) Bearer token for AUTHORIZATION header
8
- * @property {boolean} [options.proxyMode] - (Optional) Tells the API that it is running in an iframe via parent proxy
9
- */
10
1
  export declare function initializeApi(options: {
11
2
  baseURL: string;
12
3
  apiKey?: string;
@@ -14,6 +5,7 @@ export declare function initializeApi(options: {
14
5
  proxyMode?: boolean;
15
6
  ngrokSkipBrowserWarning?: boolean;
16
7
  extraHeaders?: Record<string, string>;
8
+ iframeAutoResize?: boolean;
17
9
  }): void;
18
10
  /** Enable/disable automatic "ngrok-skip-browser-warning" header. */
19
11
  export declare function setNgrokSkipBrowserWarning(flag: boolean): void;
package/dist/http.js CHANGED
@@ -17,6 +17,7 @@ let extraHeadersGlobal = {};
17
17
  * @property {string} [options.bearerToken] - (Optional) Bearer token for AUTHORIZATION header
18
18
  * @property {boolean} [options.proxyMode] - (Optional) Tells the API that it is running in an iframe via parent proxy
19
19
  */
20
+ import { enableAutoIframeResize, isIframe } from './iframe';
20
21
  export function initializeApi(options) {
21
22
  // Normalize baseURL by removing trailing slashes.
22
23
  baseURL = options.baseURL.replace(/\/+$/g, "");
@@ -30,6 +31,10 @@ export function initializeApi(options) {
30
31
  ? !!options.ngrokSkipBrowserWarning
31
32
  : inferredNgrok;
32
33
  extraHeadersGlobal = options.extraHeaders ? Object.assign({}, options.extraHeaders) : {};
34
+ // Auto-enable iframe resize unless explicitly disabled
35
+ if (isIframe() && options.iframeAutoResize !== false) {
36
+ enableAutoIframeResize();
37
+ }
33
38
  }
34
39
  /** Enable/disable automatic "ngrok-skip-browser-warning" header. */
35
40
  export function setNgrokSkipBrowserWarning(flag) {
@@ -0,0 +1,25 @@
1
+ interface IframeResizeOptions {
2
+ /** Minimum ms between height postMessages (default 100). */
3
+ intervalMs?: number;
4
+ /** Post even if height unchanged (default false). */
5
+ alwaysSend?: boolean;
6
+ /** Additional payload properties to include with each resize message. */
7
+ extra?: Record<string, any>;
8
+ /** Custom message type name (default 'smartlinks:resize'). */
9
+ messageType?: string;
10
+ }
11
+ /** Redirect parent window to a URL (if in iframe). */
12
+ export declare function redirectParent(url: string): void;
13
+ /** Request parent to adjust iframe height to current content height. */
14
+ export declare function sendHeight(height?: number, extra?: Record<string, any>): void;
15
+ /** Enable automatic height reporting to parent iframe. */
16
+ export declare function enableAutoIframeResize(options?: IframeResizeOptions): void;
17
+ /** Disable automatic height reporting. */
18
+ export declare function disableAutoIframeResize(): void;
19
+ /** Send a custom message to parent (browser-only). */
20
+ export declare function sendParentCustom(type: string, payload: Record<string, any>): void;
21
+ /** Returns true if running inside an iframe (browser). */
22
+ export declare function isIframe(): boolean;
23
+ /** Returns true if ResizeObserver is supported in current environment. */
24
+ export declare function supportsResizeObserver(): boolean;
25
+ export {};
package/dist/iframe.js ADDED
@@ -0,0 +1,123 @@
1
+ // iframe.ts
2
+ // Utilities to communicate with parent window when running inside an iframe.
3
+ // These helpers are optional and safe in non-browser / Node environments.
4
+ // They build on the existing proxyMode infrastructure but can also be used standalone.
5
+ let autoResizeTimer;
6
+ let lastHeight = 0;
7
+ let resizeOptions;
8
+ let resizeObserver;
9
+ let mutationObserver;
10
+ function isBrowser() {
11
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
12
+ }
13
+ function inIframe() {
14
+ return isBrowser() && window.parent && window.parent !== window;
15
+ }
16
+ function postParentMessage(type, payload) {
17
+ if (!inIframe())
18
+ return;
19
+ try {
20
+ window.parent.postMessage({ _smartlinksIframeMessage: true, type, payload }, '*');
21
+ }
22
+ catch (_a) {
23
+ // swallow errors silently
24
+ }
25
+ }
26
+ /** Redirect parent window to a URL (if in iframe). */
27
+ export function redirectParent(url) {
28
+ postParentMessage('smartlinks:redirect', { url });
29
+ }
30
+ /** Request parent to adjust iframe height to current content height. */
31
+ export function sendHeight(height, extra) {
32
+ if (!inIframe())
33
+ return;
34
+ const h = height !== null && height !== void 0 ? height : document.documentElement.scrollHeight;
35
+ postParentMessage((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.messageType) || 'smartlinks:resize', Object.assign(Object.assign({ height: h }, resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.extra), extra));
36
+ }
37
+ function measureHeight() {
38
+ if (!isBrowser())
39
+ return 0;
40
+ const doc = document.documentElement;
41
+ // Use max of several properties for robustness
42
+ return Math.max(doc.scrollHeight, doc.offsetHeight, doc.clientHeight, document.body ? document.body.scrollHeight : 0, document.body ? document.body.offsetHeight : 0);
43
+ }
44
+ function scheduleManualPolling() {
45
+ var _a;
46
+ if (!isBrowser())
47
+ return;
48
+ clearInterval(autoResizeTimer);
49
+ const interval = (_a = resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.intervalMs) !== null && _a !== void 0 ? _a : 100;
50
+ autoResizeTimer = window.setInterval(() => {
51
+ const h = measureHeight();
52
+ if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
53
+ lastHeight = h;
54
+ sendHeight(h);
55
+ }
56
+ }, interval);
57
+ }
58
+ function setupObservers() {
59
+ if (!isBrowser())
60
+ return;
61
+ // Prefer ResizeObserver for layout changes
62
+ if (typeof ResizeObserver !== 'undefined') {
63
+ resizeObserver = new ResizeObserver(() => {
64
+ const h = measureHeight();
65
+ if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
66
+ lastHeight = h;
67
+ sendHeight(h);
68
+ }
69
+ });
70
+ resizeObserver.observe(document.body);
71
+ }
72
+ else {
73
+ // Fallback: MutationObserver for DOM changes
74
+ mutationObserver = new MutationObserver(() => {
75
+ const h = measureHeight();
76
+ if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
77
+ lastHeight = h;
78
+ sendHeight(h);
79
+ }
80
+ });
81
+ mutationObserver.observe(document.body, { childList: true, subtree: true, attributes: true });
82
+ // Manual polling as additional safeguard
83
+ scheduleManualPolling();
84
+ }
85
+ }
86
+ /** Enable automatic height reporting to parent iframe. */
87
+ export function enableAutoIframeResize(options) {
88
+ if (!inIframe())
89
+ return;
90
+ resizeOptions = options || {};
91
+ lastHeight = measureHeight();
92
+ sendHeight(lastHeight);
93
+ setupObservers();
94
+ if (!resizeObserver) {
95
+ // If no ResizeObserver, MutationObserver is active and we also poll
96
+ scheduleManualPolling();
97
+ }
98
+ }
99
+ /** Disable automatic height reporting. */
100
+ export function disableAutoIframeResize() {
101
+ if (resizeObserver)
102
+ resizeObserver.disconnect();
103
+ if (mutationObserver)
104
+ mutationObserver.disconnect();
105
+ if (isBrowser())
106
+ clearInterval(autoResizeTimer);
107
+ resizeObserver = undefined;
108
+ mutationObserver = undefined;
109
+ autoResizeTimer = undefined;
110
+ resizeOptions = undefined;
111
+ }
112
+ /** Send a custom message to parent (browser-only). */
113
+ export function sendParentCustom(type, payload) {
114
+ postParentMessage(type, payload);
115
+ }
116
+ /** Returns true if running inside an iframe (browser). */
117
+ export function isIframe() {
118
+ return inIframe();
119
+ }
120
+ /** Returns true if ResizeObserver is supported in current environment. */
121
+ export function supportsResizeObserver() {
122
+ return typeof ResizeObserver !== 'undefined';
123
+ }
@@ -7,6 +7,25 @@ export interface AuthKitUser {
7
7
  emailVerified?: boolean;
8
8
  accountData?: Record<string, any>;
9
9
  }
10
+ export interface UserProfile {
11
+ uid: string;
12
+ email?: string;
13
+ displayName?: string | null;
14
+ phoneNumber?: string | null;
15
+ photoURL?: string | null;
16
+ emailVerified?: boolean;
17
+ accountData?: Record<string, any>;
18
+ }
19
+ export interface ProfileUpdateData {
20
+ displayName?: string;
21
+ photoURL?: string;
22
+ accountData?: Record<string, any>;
23
+ }
24
+ export interface SuccessResponse {
25
+ success: boolean;
26
+ message?: string;
27
+ token?: string;
28
+ }
10
29
  export interface AuthLoginResponse {
11
30
  token?: string;
12
31
  user: AuthKitUser;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.0.50",
3
+ "version": "1.0.52",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",