@proveanything/smartlinks 1.0.54 → 1.0.55
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 +2 -1
- package/README.md +3 -0
- package/dist/http.d.ts +9 -0
- package/dist/http.js +78 -0
- package/package.json +1 -1
package/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.55 | Generated: 2025-12-01T16:15:00.313Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -39,6 +39,7 @@ Core HTTP functions for API configuration and communication:
|
|
|
39
39
|
ngrokSkipBrowserWarning?: boolean
|
|
40
40
|
extraHeaders?: Record<string, string>
|
|
41
41
|
iframeAutoResize?: boolean // default true when in iframe
|
|
42
|
+
logger?: Logger // optional console-like or function to enable verbose logging
|
|
42
43
|
}) → `void`
|
|
43
44
|
Call this once (e.g. at app startup) to configure baseURL/auth.
|
|
44
45
|
|
package/README.md
CHANGED
|
@@ -28,6 +28,7 @@ import { initializeApi } from '@proveanything/smartlinks'
|
|
|
28
28
|
|
|
29
29
|
initializeApi({
|
|
30
30
|
baseURL: 'https://smartlinks.app/api/v1', // or 'https://smartlinks.app/api/v1/'
|
|
31
|
+
// logger: console, // optional: verbose logging of requests/responses and proxy messages
|
|
31
32
|
// apiKey: process.env.SMARTLINKS_API_KEY, // Node/server only (optional)
|
|
32
33
|
// ngrokSkipBrowserWarning: true, // adds 'ngrok-skip-browser-warning: true'
|
|
33
34
|
// extraHeaders: { 'X-Debug': '1' } // merged into every request
|
|
@@ -204,11 +205,13 @@ initializeApi({
|
|
|
204
205
|
ngrokSkipBrowserWarning?: boolean // forces header 'ngrok-skip-browser-warning: true'
|
|
205
206
|
extraHeaders?: Record<string,string> // custom headers merged in each request
|
|
206
207
|
iframeAutoResize?: boolean // default true when embedded in an iframe
|
|
208
|
+
logger?: Function | { debug?: Function; info?: Function; warn?: Function; error?: Function; log?: Function } // optional verbose logging
|
|
207
209
|
})
|
|
208
210
|
|
|
209
211
|
// Auto-detection: If baseURL contains '.ngrok.io' or '.ngrok-free.dev' the header is added automatically
|
|
210
212
|
// unless you explicitly set ngrokSkipBrowserWarning: false.
|
|
211
213
|
// Auto iframe resize: When in an iframe, resize messages are sent by default unless iframeAutoResize: false.
|
|
214
|
+
// Verbose logging: Pass a logger (e.g. console) to log outbound requests/responses and proxy postMessages.
|
|
212
215
|
```
|
|
213
216
|
|
|
214
217
|
When embedding the SDK in an iframe with `proxyMode: true`, you can also use:
|
package/dist/http.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
type Logger = {
|
|
2
|
+
debug?: (...args: any[]) => void;
|
|
3
|
+
info?: (...args: any[]) => void;
|
|
4
|
+
warn?: (...args: any[]) => void;
|
|
5
|
+
error?: (...args: any[]) => void;
|
|
6
|
+
log?: (...args: any[]) => void;
|
|
7
|
+
} | ((...args: any[]) => void);
|
|
1
8
|
export declare function initializeApi(options: {
|
|
2
9
|
baseURL: string;
|
|
3
10
|
apiKey?: string;
|
|
@@ -6,6 +13,7 @@ export declare function initializeApi(options: {
|
|
|
6
13
|
ngrokSkipBrowserWarning?: boolean;
|
|
7
14
|
extraHeaders?: Record<string, string>;
|
|
8
15
|
iframeAutoResize?: boolean;
|
|
16
|
+
logger?: Logger;
|
|
9
17
|
}): void;
|
|
10
18
|
/** Enable/disable automatic "ngrok-skip-browser-warning" header. */
|
|
11
19
|
export declare function setNgrokSkipBrowserWarning(flag: boolean): void;
|
|
@@ -60,3 +68,4 @@ export declare function getApiHeaders(): Record<string, string>;
|
|
|
60
68
|
* @returns The data from the proxy response
|
|
61
69
|
*/
|
|
62
70
|
export declare function sendCustomProxyMessage<T = any>(request: string, params: any): Promise<T>;
|
|
71
|
+
export {};
|
package/dist/http.js
CHANGED
|
@@ -8,6 +8,57 @@ let bearerToken = undefined;
|
|
|
8
8
|
let proxyMode = false;
|
|
9
9
|
let ngrokSkipBrowserWarning = false;
|
|
10
10
|
let extraHeadersGlobal = {};
|
|
11
|
+
let logger;
|
|
12
|
+
function logDebug(...args) {
|
|
13
|
+
if (!logger)
|
|
14
|
+
return;
|
|
15
|
+
if (typeof logger === 'function')
|
|
16
|
+
return logger(...args);
|
|
17
|
+
if (logger.debug)
|
|
18
|
+
return logger.debug(...args);
|
|
19
|
+
if (logger.log)
|
|
20
|
+
return logger.log(...args);
|
|
21
|
+
}
|
|
22
|
+
function maskSensitive(value) {
|
|
23
|
+
if (!value)
|
|
24
|
+
return value;
|
|
25
|
+
if (value.length <= 8)
|
|
26
|
+
return '*'.repeat(Math.max(4, value.length));
|
|
27
|
+
return value.slice(0, 2) + '***' + value.slice(-4);
|
|
28
|
+
}
|
|
29
|
+
function redactHeaders(headers) {
|
|
30
|
+
const h = Object.assign({}, headers);
|
|
31
|
+
for (const key of Object.keys(h)) {
|
|
32
|
+
const k = key.toLowerCase();
|
|
33
|
+
if (k === 'authorization' || k === 'x-api-key' || k === 'auth' || k === 'proxy-authorization') {
|
|
34
|
+
h[key] = maskSensitive(h[key]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return h;
|
|
38
|
+
}
|
|
39
|
+
function safeBodyPreview(body) {
|
|
40
|
+
if (body == null)
|
|
41
|
+
return undefined;
|
|
42
|
+
if (typeof FormData !== 'undefined' && body instanceof FormData)
|
|
43
|
+
return '[FormData]';
|
|
44
|
+
if (typeof body === 'string')
|
|
45
|
+
return body.slice(0, 1000);
|
|
46
|
+
if (typeof body === 'object') {
|
|
47
|
+
const copy = Array.isArray(body) ? [...body] : Object.assign({}, body);
|
|
48
|
+
const redactKeys = ['password', 'token', 'authorization', 'apiKey', 'bearerToken'];
|
|
49
|
+
for (const k of Object.keys(copy)) {
|
|
50
|
+
if (redactKeys.includes(k))
|
|
51
|
+
copy[k] = '[redacted]';
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(JSON.stringify(copy));
|
|
55
|
+
}
|
|
56
|
+
catch (_a) {
|
|
57
|
+
return '[Object]';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return body;
|
|
61
|
+
}
|
|
11
62
|
/**
|
|
12
63
|
* Call this once (e.g. at app startup) to configure baseURL/auth.
|
|
13
64
|
*
|
|
@@ -35,6 +86,15 @@ export function initializeApi(options) {
|
|
|
35
86
|
if (isIframe() && options.iframeAutoResize !== false) {
|
|
36
87
|
enableAutoIframeResize();
|
|
37
88
|
}
|
|
89
|
+
logger = options.logger;
|
|
90
|
+
logDebug('[smartlinks] initializeApi', {
|
|
91
|
+
baseURL,
|
|
92
|
+
proxyMode,
|
|
93
|
+
inferredNgrok,
|
|
94
|
+
ngrokSkipBrowserWarning,
|
|
95
|
+
extraHeaders: Object.keys(extraHeadersGlobal),
|
|
96
|
+
iframeAutoResizeEnabled: isIframe() && options.iframeAutoResize !== false,
|
|
97
|
+
});
|
|
38
98
|
}
|
|
39
99
|
/** Enable/disable automatic "ngrok-skip-browser-warning" header. */
|
|
40
100
|
export function setNgrokSkipBrowserWarning(flag) {
|
|
@@ -63,6 +123,7 @@ function ensureProxyListener() {
|
|
|
63
123
|
const msg = event.data;
|
|
64
124
|
if (!msg || !msg._smartlinksProxyResponse || !msg.id)
|
|
65
125
|
return;
|
|
126
|
+
logDebug('[smartlinks] proxy:response', { id: msg.id, ok: !msg.error, keys: Object.keys(msg) });
|
|
66
127
|
const pending = proxyPending[msg.id];
|
|
67
128
|
if (pending) {
|
|
68
129
|
if (msg.error) {
|
|
@@ -89,6 +150,7 @@ async function proxyRequest(method, path, body, headers, options) {
|
|
|
89
150
|
headers,
|
|
90
151
|
options,
|
|
91
152
|
};
|
|
153
|
+
logDebug('[smartlinks] proxy:postMessage', { id, method, path, headers: headers ? redactHeaders(headers) : undefined, hasBody: !!body });
|
|
92
154
|
return new Promise((resolve, reject) => {
|
|
93
155
|
proxyPending[id] = { resolve, reject };
|
|
94
156
|
window.parent.postMessage(msg, "*");
|
|
@@ -102,6 +164,7 @@ async function proxyRequest(method, path, body, headers, options) {
|
|
|
102
164
|
*/
|
|
103
165
|
export async function request(path) {
|
|
104
166
|
if (proxyMode) {
|
|
167
|
+
logDebug('[smartlinks] GET via proxy', { path });
|
|
105
168
|
return proxyRequest("GET", path);
|
|
106
169
|
}
|
|
107
170
|
if (!baseURL) {
|
|
@@ -117,10 +180,12 @@ export async function request(path) {
|
|
|
117
180
|
headers["ngrok-skip-browser-warning"] = "true";
|
|
118
181
|
for (const [k, v] of Object.entries(extraHeadersGlobal))
|
|
119
182
|
headers[k] = v;
|
|
183
|
+
logDebug('[smartlinks] GET fetch', { url, headers: redactHeaders(headers) });
|
|
120
184
|
const response = await fetch(url, {
|
|
121
185
|
method: "GET",
|
|
122
186
|
headers,
|
|
123
187
|
});
|
|
188
|
+
logDebug('[smartlinks] GET response', { url, status: response.status, ok: response.ok });
|
|
124
189
|
if (!response.ok) {
|
|
125
190
|
// Try to parse ErrorResponse; if that fails, throw generic
|
|
126
191
|
try {
|
|
@@ -141,6 +206,7 @@ export async function request(path) {
|
|
|
141
206
|
*/
|
|
142
207
|
export async function post(path, body, extraHeaders) {
|
|
143
208
|
if (proxyMode) {
|
|
209
|
+
logDebug('[smartlinks] POST via proxy', { path, body: safeBodyPreview(body) });
|
|
144
210
|
return proxyRequest("POST", path, body, extraHeaders);
|
|
145
211
|
}
|
|
146
212
|
if (!baseURL) {
|
|
@@ -161,11 +227,13 @@ export async function post(path, body, extraHeaders) {
|
|
|
161
227
|
if (!(body instanceof FormData)) {
|
|
162
228
|
headers["Content-Type"] = "application/json";
|
|
163
229
|
}
|
|
230
|
+
logDebug('[smartlinks] POST fetch', { url, headers: redactHeaders(headers), body: safeBodyPreview(body) });
|
|
164
231
|
const response = await fetch(url, {
|
|
165
232
|
method: "POST",
|
|
166
233
|
headers,
|
|
167
234
|
body: body instanceof FormData ? body : JSON.stringify(body),
|
|
168
235
|
});
|
|
236
|
+
logDebug('[smartlinks] POST response', { url, status: response.status, ok: response.ok });
|
|
169
237
|
if (!response.ok) {
|
|
170
238
|
try {
|
|
171
239
|
const errBody = (await response.json());
|
|
@@ -185,6 +253,7 @@ export async function post(path, body, extraHeaders) {
|
|
|
185
253
|
*/
|
|
186
254
|
export async function put(path, body, extraHeaders) {
|
|
187
255
|
if (proxyMode) {
|
|
256
|
+
logDebug('[smartlinks] PUT via proxy', { path, body: safeBodyPreview(body) });
|
|
188
257
|
return proxyRequest("PUT", path, body, extraHeaders);
|
|
189
258
|
}
|
|
190
259
|
if (!baseURL) {
|
|
@@ -205,11 +274,13 @@ export async function put(path, body, extraHeaders) {
|
|
|
205
274
|
if (!(body instanceof FormData)) {
|
|
206
275
|
headers["Content-Type"] = "application/json";
|
|
207
276
|
}
|
|
277
|
+
logDebug('[smartlinks] PUT fetch', { url, headers: redactHeaders(headers), body: safeBodyPreview(body) });
|
|
208
278
|
const response = await fetch(url, {
|
|
209
279
|
method: "PUT",
|
|
210
280
|
headers,
|
|
211
281
|
body: body instanceof FormData ? body : JSON.stringify(body),
|
|
212
282
|
});
|
|
283
|
+
logDebug('[smartlinks] PUT response', { url, status: response.status, ok: response.ok });
|
|
213
284
|
if (!response.ok) {
|
|
214
285
|
try {
|
|
215
286
|
const errBody = (await response.json());
|
|
@@ -228,6 +299,7 @@ export async function put(path, body, extraHeaders) {
|
|
|
228
299
|
*/
|
|
229
300
|
export async function requestWithOptions(path, options) {
|
|
230
301
|
if (proxyMode) {
|
|
302
|
+
logDebug('[smartlinks] requestWithOptions via proxy', { path, method: options.method || 'GET' });
|
|
231
303
|
return proxyRequest(options.method || "GET", path, options.body, options.headers, options);
|
|
232
304
|
}
|
|
233
305
|
if (!baseURL) {
|
|
@@ -256,7 +328,9 @@ export async function requestWithOptions(path, options) {
|
|
|
256
328
|
for (const [k, v] of Object.entries(extraHeadersGlobal))
|
|
257
329
|
if (!(k in headers))
|
|
258
330
|
headers[k] = v;
|
|
331
|
+
logDebug('[smartlinks] requestWithOptions fetch', { url, method: options.method || 'GET', headers: redactHeaders(headers), body: safeBodyPreview(options.body) });
|
|
259
332
|
const response = await fetch(url, Object.assign(Object.assign({}, options), { headers }));
|
|
333
|
+
logDebug('[smartlinks] requestWithOptions response', { url, status: response.status, ok: response.ok });
|
|
260
334
|
if (!response.ok) {
|
|
261
335
|
try {
|
|
262
336
|
const errBody = (await response.json());
|
|
@@ -275,6 +349,7 @@ export async function requestWithOptions(path, options) {
|
|
|
275
349
|
*/
|
|
276
350
|
export async function del(path, extraHeaders) {
|
|
277
351
|
if (proxyMode) {
|
|
352
|
+
logDebug('[smartlinks] DELETE via proxy', { path });
|
|
278
353
|
return proxyRequest("DELETE", path, undefined, extraHeaders);
|
|
279
354
|
}
|
|
280
355
|
if (!baseURL) {
|
|
@@ -291,10 +366,12 @@ export async function del(path, extraHeaders) {
|
|
|
291
366
|
for (const [k, v] of Object.entries(extraHeadersGlobal))
|
|
292
367
|
if (!(k in headers))
|
|
293
368
|
headers[k] = v;
|
|
369
|
+
logDebug('[smartlinks] DELETE fetch', { url, headers: redactHeaders(headers) });
|
|
294
370
|
const response = await fetch(url, {
|
|
295
371
|
method: "DELETE",
|
|
296
372
|
headers,
|
|
297
373
|
});
|
|
374
|
+
logDebug('[smartlinks] DELETE response', { url, status: response.status, ok: response.ok });
|
|
298
375
|
if (!response.ok) {
|
|
299
376
|
try {
|
|
300
377
|
const errBody = (await response.json());
|
|
@@ -345,6 +422,7 @@ export async function sendCustomProxyMessage(request, params) {
|
|
|
345
422
|
request,
|
|
346
423
|
params,
|
|
347
424
|
};
|
|
425
|
+
logDebug('[smartlinks] proxy:custom postMessage', { id, request, params: safeBodyPreview(params) });
|
|
348
426
|
return new Promise((resolve, reject) => {
|
|
349
427
|
proxyPending[id] = { resolve, reject };
|
|
350
428
|
window.parent.postMessage(msg, "*");
|