@relume_io/partner-node 2.0.1 → 2.2.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 +152 -207
- package/dist/bin.cjs +44 -4
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +39 -5
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-HPVVBUR7.js → chunk-WUW4CIBP.js} +201 -1
- package/dist/chunk-WUW4CIBP.js.map +1 -0
- package/dist/index.cjs +51 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -4
- package/dist/index.d.ts +34 -4
- package/dist/index.js +30 -178
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-HPVVBUR7.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -419,7 +419,7 @@ function isHttpsUrl(value) {
|
|
|
419
419
|
|
|
420
420
|
// src/api.ts
|
|
421
421
|
var DEFAULT_API_BASE_URL = "https://apis.relume.io/nova/partner/v1";
|
|
422
|
-
var SDK_VERSION = "2.0
|
|
422
|
+
var SDK_VERSION = "2.2.0";
|
|
423
423
|
var USER_AGENT = `relume-partner-node/${SDK_VERSION}`;
|
|
424
424
|
var DEFAULT_API_TIMEOUT_MS = 15e3;
|
|
425
425
|
var DEFAULT_MAX_RETRIES = 2;
|
|
@@ -577,6 +577,11 @@ var CALL_TYPES = [
|
|
|
577
577
|
"credits.charge",
|
|
578
578
|
"credits.reverse"
|
|
579
579
|
];
|
|
580
|
+
function keyEnvironment(secretKey) {
|
|
581
|
+
if (secretKey.startsWith("sk_test_")) return "test";
|
|
582
|
+
if (secretKey.startsWith("sk_live_")) return "live";
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
580
585
|
var InvalidCallbackResultError = class extends Error {
|
|
581
586
|
constructor(message) {
|
|
582
587
|
super(message);
|
|
@@ -589,10 +594,19 @@ function optionalString(value, max) {
|
|
|
589
594
|
}
|
|
590
595
|
return isString(value, 1, max) ? { ok: true, value } : { ok: false };
|
|
591
596
|
}
|
|
597
|
+
function optionalStrings(value, max, maxItems) {
|
|
598
|
+
if (value === void 0 || value === null) {
|
|
599
|
+
return { ok: true, value: void 0 };
|
|
600
|
+
}
|
|
601
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > maxItems || !value.every((item) => isString(item, 1, max))) {
|
|
602
|
+
return { ok: false };
|
|
603
|
+
}
|
|
604
|
+
return { ok: true, value: [...value] };
|
|
605
|
+
}
|
|
592
606
|
function isCallType(value) {
|
|
593
607
|
return CALL_TYPES.some((type) => type === value);
|
|
594
608
|
}
|
|
595
|
-
function parseCall(body) {
|
|
609
|
+
function parseCall(body, environment) {
|
|
596
610
|
if (!isRecord(body)) {
|
|
597
611
|
return {
|
|
598
612
|
ok: false,
|
|
@@ -614,6 +628,17 @@ function parseCall(body) {
|
|
|
614
628
|
message: `Invalid ${field} for ${type}.`,
|
|
615
629
|
type
|
|
616
630
|
});
|
|
631
|
+
if (body.environment !== void 0 && body.environment !== "test" && body.environment !== "live") {
|
|
632
|
+
return invalid("environment");
|
|
633
|
+
}
|
|
634
|
+
if (body.environment !== void 0 && body.environment !== environment) {
|
|
635
|
+
return {
|
|
636
|
+
ok: false,
|
|
637
|
+
code: "environment_mismatch",
|
|
638
|
+
message: `This ${type} is for ${body.environment}, but this server's secret key is for ${environment}.`,
|
|
639
|
+
type
|
|
640
|
+
};
|
|
641
|
+
}
|
|
617
642
|
const { userId } = body;
|
|
618
643
|
if (!isString(userId, 1, 128)) return invalid("userId");
|
|
619
644
|
switch (type) {
|
|
@@ -631,6 +656,8 @@ function parseCall(body) {
|
|
|
631
656
|
if (!siteId.ok) return invalid("siteId");
|
|
632
657
|
const pageId = optionalString(body.pageId, 200);
|
|
633
658
|
if (!pageId.ok) return invalid("pageId");
|
|
659
|
+
const pageIds = optionalStrings(body.pageIds, 200, 1e3);
|
|
660
|
+
if (!pageIds.ok) return invalid("pageIds");
|
|
634
661
|
const charge = {
|
|
635
662
|
userId,
|
|
636
663
|
chargeId,
|
|
@@ -641,6 +668,7 @@ function parseCall(body) {
|
|
|
641
668
|
};
|
|
642
669
|
if (siteId.value !== void 0) charge.siteId = siteId.value;
|
|
643
670
|
if (pageId.value !== void 0) charge.pageId = pageId.value;
|
|
671
|
+
if (pageIds.value !== void 0) charge.pageIds = pageIds.value;
|
|
644
672
|
return { ok: true, call: { type, charge } };
|
|
645
673
|
}
|
|
646
674
|
case "credits.reverse": {
|
|
@@ -799,8 +827,9 @@ var isLedgerEntryDetail = hasStrings(
|
|
|
799
827
|
"type",
|
|
800
828
|
"status"
|
|
801
829
|
);
|
|
830
|
+
var isCreditUnit = hasStrings("singular", "plural");
|
|
802
831
|
function isPriceList(value) {
|
|
803
|
-
return isRecord(value) && Array.isArray(value.data);
|
|
832
|
+
return isRecord(value) && Array.isArray(value.data) && isCreditUnit(value.creditUnit);
|
|
804
833
|
}
|
|
805
834
|
function segment(name, value) {
|
|
806
835
|
if (typeof value !== "string" || value === "") {
|
|
@@ -879,7 +908,8 @@ function partnerApi(config) {
|
|
|
879
908
|
})
|
|
880
909
|
},
|
|
881
910
|
prices: {
|
|
882
|
-
list: async () => (await get("/prices", isPriceList)).data
|
|
911
|
+
list: async () => (await get("/prices", isPriceList)).data,
|
|
912
|
+
get: () => get("/prices", isPriceList)
|
|
883
913
|
}
|
|
884
914
|
};
|
|
885
915
|
}
|
|
@@ -974,6 +1004,7 @@ var Relume = class _Relume {
|
|
|
974
1004
|
*/
|
|
975
1005
|
fetchHandler;
|
|
976
1006
|
#secretKey;
|
|
1007
|
+
#environment;
|
|
977
1008
|
#api;
|
|
978
1009
|
#callbacks = {};
|
|
979
1010
|
#onHandlerError;
|
|
@@ -993,6 +1024,12 @@ var Relume = class _Relume {
|
|
|
993
1024
|
"Relume.init: that is a publishable key. Pass the secret key (sk_\u2026); the publishable key goes to the embed."
|
|
994
1025
|
);
|
|
995
1026
|
}
|
|
1027
|
+
const environment = keyEnvironment(secretKey);
|
|
1028
|
+
if (environment === null) {
|
|
1029
|
+
throw new TypeError(
|
|
1030
|
+
"Relume.init: secretKey must start with sk_test_ or sk_live_."
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
996
1033
|
const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
997
1034
|
if (!Number.isSafeInteger(maxRetries) || maxRetries < 0) {
|
|
998
1035
|
throw new TypeError(
|
|
@@ -1000,6 +1037,7 @@ var Relume = class _Relume {
|
|
|
1000
1037
|
);
|
|
1001
1038
|
}
|
|
1002
1039
|
this.#secretKey = secretKey;
|
|
1040
|
+
this.#environment = environment;
|
|
1003
1041
|
this.#now = options.now ?? Date.now;
|
|
1004
1042
|
this.#api = {
|
|
1005
1043
|
secretKey,
|
|
@@ -1075,8 +1113,9 @@ var Relume = class _Relume {
|
|
|
1075
1113
|
}
|
|
1076
1114
|
/**
|
|
1077
1115
|
* `POST /relume/calls`, framework-agnostic: verifies the signature and the
|
|
1078
|
-
* 5-minute window,
|
|
1079
|
-
*
|
|
1116
|
+
* 5-minute window, refuses a call for another environment than the secret
|
|
1117
|
+
* key's (`400 environment_mismatch`), routes by `type`, runs your callback
|
|
1118
|
+
* and validates what it returns. Pass the raw body exactly as received.
|
|
1080
1119
|
*/
|
|
1081
1120
|
async handleCall(input) {
|
|
1082
1121
|
const requestId = input.requestId ?? null;
|
|
@@ -1100,10 +1139,14 @@ var Relume = class _Relume {
|
|
|
1100
1139
|
"The body is not valid JSON."
|
|
1101
1140
|
);
|
|
1102
1141
|
}
|
|
1103
|
-
const parsed = parseCall(body);
|
|
1142
|
+
const parsed = parseCall(body, this.#environment);
|
|
1104
1143
|
if (!parsed.ok) return errorResponse(400, parsed.code, parsed.message);
|
|
1105
1144
|
const { call } = parsed;
|
|
1106
|
-
const context = {
|
|
1145
|
+
const context = {
|
|
1146
|
+
type: call.type,
|
|
1147
|
+
environment: this.#environment,
|
|
1148
|
+
requestId
|
|
1149
|
+
};
|
|
1107
1150
|
const callbackName = CALLBACK_FOR[call.type];
|
|
1108
1151
|
if (!this.#callbacks[callbackName]) {
|
|
1109
1152
|
this.#onHandlerError(
|