framepayments 2.3.1 → 2.4.0
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/README.md +36 -0
- package/dist/index.cjs +81 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +38 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +81 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -15,12 +15,14 @@ var FrameAPIError = class extends Error {
|
|
|
15
15
|
};
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/client.ts
|
|
18
|
-
const
|
|
18
|
+
const FRAME_USE_PUBLISHABLE_KEY = "frameUsePublishableKey";
|
|
19
|
+
const FRAME_AUTH_TOKEN = "frameAuthToken";
|
|
20
|
+
const createOnboardingSessionStore = () => ({ token: null });
|
|
19
21
|
function safeRawFromAxiosError(err) {
|
|
20
22
|
if (!err || typeof err !== "object") return err;
|
|
21
23
|
const cleanedConfig = err.config ? (() => {
|
|
22
|
-
const { headers, ...restConfig } = err.config;
|
|
23
|
-
const cleanedHeaders = headers && typeof headers === "object" ? Object.fromEntries(Object.entries(headers).filter(([k]) => k.toLowerCase() !== "authorization"
|
|
24
|
+
const { headers, [FRAME_AUTH_TOKEN]: _authToken, ...restConfig } = err.config;
|
|
25
|
+
const cleanedHeaders = headers && typeof headers === "object" ? Object.fromEntries(Object.entries(headers).filter(([k]) => k.toLowerCase() !== "authorization")) : headers;
|
|
24
26
|
return {
|
|
25
27
|
...restConfig,
|
|
26
28
|
headers: cleanedHeaders
|
|
@@ -33,7 +35,7 @@ function safeRawFromAxiosError(err) {
|
|
|
33
35
|
config: cleanedConfig
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
|
-
const createApiClient = (config) => {
|
|
38
|
+
const createApiClient = (config, sessionStore = createOnboardingSessionStore()) => {
|
|
37
39
|
const { apiKey, publishableKey, defaultHeaders } = config;
|
|
38
40
|
if (!apiKey && !publishableKey) throw new Error("FrameSDK config requires at least one of: apiKey, publishableKey. Mobile clients should ship publishableKey only; server code should use apiKey.");
|
|
39
41
|
const baseURL = config.baseURL ?? "https://api.framepayments.com";
|
|
@@ -43,9 +45,11 @@ const createApiClient = (config) => {
|
|
|
43
45
|
});
|
|
44
46
|
client.interceptors.request.use((requestConfig) => {
|
|
45
47
|
const headers = requestConfig.headers;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const cfg = requestConfig;
|
|
49
|
+
const wantsPublishable = cfg.frameUsePublishableKey === true;
|
|
50
|
+
const rawAuthToken = cfg.frameAuthToken;
|
|
51
|
+
if (rawAuthToken === "") throw new FrameAPIError("Frame authToken was provided but empty. Pass a non-empty client_secret (e.g. ci_..._secret_...), or omit authToken to use the configured key.", "invalid_auth_token", 0, null);
|
|
52
|
+
const perRequestAuthToken = typeof rawAuthToken === "string" && rawAuthToken.length > 0 ? rawAuthToken : void 0;
|
|
49
53
|
if (defaultHeaders) for (const [name, value] of Object.entries(defaultHeaders)) {
|
|
50
54
|
if (value == null) continue;
|
|
51
55
|
if (headers instanceof AxiosHeaders) {
|
|
@@ -55,10 +59,17 @@ const createApiClient = (config) => {
|
|
|
55
59
|
if (h[name] === void 0) h[name] = value;
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
else if (
|
|
62
|
+
const sessionToken = sessionStore.token;
|
|
63
|
+
let bearer;
|
|
64
|
+
if (perRequestAuthToken) bearer = perRequestAuthToken;
|
|
65
|
+
else if (sessionToken) bearer = sessionToken;
|
|
66
|
+
else {
|
|
67
|
+
const keyToUse = wantsPublishable ? publishableKey : apiKey;
|
|
68
|
+
if (!keyToUse) throw new FrameAPIError(wantsPublishable ? "Frame publishable key is not configured. Pass { publishableKey } to new FrameSDK(...) before calling endpoints with { usePublishableKey: true }." : "Frame API key is not configured. Pass { apiKey } to new FrameSDK(...) before calling secret-keyed endpoints.", wantsPublishable ? "missing_publishable_key" : "missing_api_key", 0, null);
|
|
69
|
+
bearer = keyToUse;
|
|
70
|
+
}
|
|
71
|
+
if (headers instanceof AxiosHeaders) headers.set("Authorization", `Bearer ${bearer}`);
|
|
72
|
+
else if (headers) headers["Authorization"] = `Bearer ${bearer}`;
|
|
62
73
|
return requestConfig;
|
|
63
74
|
});
|
|
64
75
|
client.interceptors.response.use((response) => response, (error) => {
|
|
@@ -72,33 +83,18 @@ const createApiClient = (config) => {
|
|
|
72
83
|
});
|
|
73
84
|
return client;
|
|
74
85
|
};
|
|
86
|
+
function buildRequestConfig(publishableDefault, opts) {
|
|
87
|
+
const { usePublishableKey = publishableDefault, authToken, ...rest } = opts ?? {};
|
|
88
|
+
const cfg = { ...rest };
|
|
89
|
+
if (usePublishableKey) cfg[FRAME_USE_PUBLISHABLE_KEY] = true;
|
|
90
|
+
if (authToken !== void 0) cfg[FRAME_AUTH_TOKEN] = authToken;
|
|
91
|
+
return cfg;
|
|
92
|
+
}
|
|
75
93
|
function withPublishableKey(opts) {
|
|
76
|
-
|
|
77
|
-
if (!usePublishableKey) return headers ? {
|
|
78
|
-
...rest,
|
|
79
|
-
headers
|
|
80
|
-
} : { ...rest };
|
|
81
|
-
return {
|
|
82
|
-
...rest,
|
|
83
|
-
headers: {
|
|
84
|
-
...headers ?? {},
|
|
85
|
-
[PUBLISHABLE_FLAG_KEY]: "1"
|
|
86
|
-
}
|
|
87
|
-
};
|
|
94
|
+
return buildRequestConfig(true, opts);
|
|
88
95
|
}
|
|
89
96
|
function maybePublishableKey(opts) {
|
|
90
|
-
|
|
91
|
-
if (!usePublishableKey) return headers ? {
|
|
92
|
-
...rest,
|
|
93
|
-
headers
|
|
94
|
-
} : { ...rest };
|
|
95
|
-
return {
|
|
96
|
-
...rest,
|
|
97
|
-
headers: {
|
|
98
|
-
...headers ?? {},
|
|
99
|
-
[PUBLISHABLE_FLAG_KEY]: "1"
|
|
100
|
-
}
|
|
101
|
-
};
|
|
97
|
+
return buildRequestConfig(false, opts);
|
|
102
98
|
}
|
|
103
99
|
//#endregion
|
|
104
100
|
//#region src/utils/paginator.ts
|
|
@@ -166,11 +162,11 @@ var CapabilitiesAPI = class {
|
|
|
166
162
|
constructor(client) {
|
|
167
163
|
this.client = client;
|
|
168
164
|
}
|
|
169
|
-
async list(accountId) {
|
|
170
|
-
return (await this.client.get(`/v1/accounts/${accountId}/capabilities
|
|
165
|
+
async list(accountId, opts) {
|
|
166
|
+
return (await this.client.get(`/v1/accounts/${accountId}/capabilities`, maybePublishableKey(opts))).data;
|
|
171
167
|
}
|
|
172
|
-
async request(accountId, params) {
|
|
173
|
-
return (await this.client.post(`/v1/accounts/${accountId}/capabilities`, params)).data;
|
|
168
|
+
async request(accountId, params, opts) {
|
|
169
|
+
return (await this.client.post(`/v1/accounts/${accountId}/capabilities`, params, maybePublishableKey(opts))).data;
|
|
174
170
|
}
|
|
175
171
|
async get(accountId, name) {
|
|
176
172
|
return (await this.client.get(`/v1/accounts/${accountId}/capabilities/${name}`)).data;
|
|
@@ -185,11 +181,14 @@ var OnboardingSessionsAPI = class {
|
|
|
185
181
|
constructor(client) {
|
|
186
182
|
this.client = client;
|
|
187
183
|
}
|
|
188
|
-
async create(params) {
|
|
189
|
-
return (await this.client.post("/v1/onboarding_sessions", params)).data;
|
|
184
|
+
async create(params, opts) {
|
|
185
|
+
return (await this.client.post("/v1/onboarding_sessions", params, maybePublishableKey(opts))).data;
|
|
190
186
|
}
|
|
191
|
-
async getByAccount(accountId) {
|
|
192
|
-
return (await this.client.get("/v1/onboarding_sessions", {
|
|
187
|
+
async getByAccount(accountId, opts) {
|
|
188
|
+
return (await this.client.get("/v1/onboarding_sessions", {
|
|
189
|
+
...maybePublishableKey(opts),
|
|
190
|
+
params: { account_id: accountId }
|
|
191
|
+
})).data;
|
|
193
192
|
}
|
|
194
193
|
};
|
|
195
194
|
//#endregion
|
|
@@ -318,8 +317,8 @@ var ChargeIntentsAPI = class {
|
|
|
318
317
|
async update(id, params) {
|
|
319
318
|
return (await this.client.patch(`/v1/charge_intents/${id}`, params)).data;
|
|
320
319
|
}
|
|
321
|
-
async get(id) {
|
|
322
|
-
return (await this.client.get(`/v1/charge_intents/${id}
|
|
320
|
+
async get(id, opts) {
|
|
321
|
+
return (await this.client.get(`/v1/charge_intents/${id}`, maybePublishableKey(opts))).data;
|
|
323
322
|
}
|
|
324
323
|
async list(per_page, page) {
|
|
325
324
|
return (await this.client.get("/v1/charge_intents", { params: {
|
|
@@ -976,14 +975,14 @@ var ThreeDSAPI = class {
|
|
|
976
975
|
constructor(client) {
|
|
977
976
|
this.client = client;
|
|
978
977
|
}
|
|
979
|
-
async create(params) {
|
|
980
|
-
return (await this.client.post("/v1/3ds/intents", params)).data;
|
|
978
|
+
async create(params, opts) {
|
|
979
|
+
return (await this.client.post("/v1/3ds/intents", params, maybePublishableKey(opts))).data;
|
|
981
980
|
}
|
|
982
|
-
async get(id) {
|
|
983
|
-
return (await this.client.get(`/v1/3ds/intents/${id}
|
|
981
|
+
async get(id, opts) {
|
|
982
|
+
return (await this.client.get(`/v1/3ds/intents/${id}`, maybePublishableKey(opts))).data;
|
|
984
983
|
}
|
|
985
|
-
async resend(id) {
|
|
986
|
-
return (await this.client.post(`/v1/3ds/intents/${id}/resend
|
|
984
|
+
async resend(id, opts) {
|
|
985
|
+
return (await this.client.post(`/v1/3ds/intents/${id}/resend`, void 0, maybePublishableKey(opts))).data;
|
|
987
986
|
}
|
|
988
987
|
};
|
|
989
988
|
//#endregion
|
|
@@ -1028,8 +1027,8 @@ var TermsOfServiceAPI = class {
|
|
|
1028
1027
|
constructor(client) {
|
|
1029
1028
|
this.client = client;
|
|
1030
1029
|
}
|
|
1031
|
-
async createToken() {
|
|
1032
|
-
return (await this.client.post("/v1/terms_of_service", {})).data;
|
|
1030
|
+
async createToken(opts) {
|
|
1031
|
+
return (await this.client.post("/v1/terms_of_service", {}, maybePublishableKey(opts))).data;
|
|
1033
1032
|
}
|
|
1034
1033
|
async update(params) {
|
|
1035
1034
|
return (await this.client.patch("/v1/terms_of_service", params)).data;
|
|
@@ -1107,7 +1106,8 @@ var GeoComplianceAPI = class {
|
|
|
1107
1106
|
//#region src/index.ts
|
|
1108
1107
|
var FrameSDK = class {
|
|
1109
1108
|
constructor(config) {
|
|
1110
|
-
|
|
1109
|
+
this.onboardingSessionStore = createOnboardingSessionStore();
|
|
1110
|
+
const client = createApiClient(config, this.onboardingSessionStore);
|
|
1111
1111
|
this.accounts = new AccountsAPI(client);
|
|
1112
1112
|
this.capabilities = new CapabilitiesAPI(client);
|
|
1113
1113
|
this.onboardingSessions = new OnboardingSessionsAPI(client);
|
|
@@ -1147,6 +1147,33 @@ var FrameSDK = class {
|
|
|
1147
1147
|
this.wallet = new WalletAPI(client);
|
|
1148
1148
|
this.geoCompliance = new GeoComplianceAPI(client);
|
|
1149
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Begin an onboarding session. While a session is active, every request sends
|
|
1152
|
+
* `Authorization: Bearer <token>` (e.g. an `onb_sess_...` token), overriding
|
|
1153
|
+
* the configured publishable/secret keys regardless of `usePublishableKey`.
|
|
1154
|
+
* A per-request `authToken` (object client_secret) still takes precedence.
|
|
1155
|
+
*
|
|
1156
|
+
* Mirrors the native iOS `beginOnboardingSession`.
|
|
1157
|
+
*/
|
|
1158
|
+
setOnboardingSession(token) {
|
|
1159
|
+
this.onboardingSessionStore.token = token;
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* End the active onboarding session, reverting auth to the configured
|
|
1163
|
+
* publishable/secret keys.
|
|
1164
|
+
*
|
|
1165
|
+
* Safe-clear: when `token` is provided, the session is cleared only if it
|
|
1166
|
+
* matches the currently active token. This mirrors Android's guarded
|
|
1167
|
+
* teardown so a stale unmount cannot wipe a newer session. Omit `token` to
|
|
1168
|
+
* force-clear unconditionally.
|
|
1169
|
+
*
|
|
1170
|
+
* @returns true if a session was cleared, false if the guard prevented it.
|
|
1171
|
+
*/
|
|
1172
|
+
clearOnboardingSession(token) {
|
|
1173
|
+
if (token !== void 0 && this.onboardingSessionStore.token !== token) return false;
|
|
1174
|
+
this.onboardingSessionStore.token = null;
|
|
1175
|
+
return true;
|
|
1176
|
+
}
|
|
1150
1177
|
};
|
|
1151
1178
|
//#endregion
|
|
1152
1179
|
export { FrameAPIError, FrameSDK, maybePublishableKey, paginate, withPublishableKey };
|