priceos 1.0.21 → 1.0.22
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 +28 -1
- package/dist/{chunk-SMK7KTGQ.js → chunk-E3XCMBGY.js} +70 -26
- package/dist/chunk-E3XCMBGY.js.map +1 -0
- package/dist/client.d.ts +2 -3
- package/dist/embed/pricing-table.global.js +7 -7
- package/dist/gen/openapi.d.ts +192 -312
- package/dist/index.cjs +69 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/next.cjs +215 -38
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +147 -14
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +104 -73
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +29 -6
- package/dist/react.js +102 -73
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +3 -6
- package/package.json +1 -1
- package/dist/chunk-SMK7KTGQ.js.map +0 -1
package/dist/next.cjs
CHANGED
|
@@ -58,19 +58,16 @@ var getRetryDelayMs = (retryCount) => {
|
|
|
58
58
|
return Math.min(RETRY_DELAY_CAP_MS, backoff + jitter);
|
|
59
59
|
};
|
|
60
60
|
var resolveIdempotencyKey = (input) => {
|
|
61
|
-
const providedEventKey = typeof input.eventKey === "string" ? input.eventKey.trim() : "";
|
|
62
61
|
const providedIdempotencyKey = typeof input.idempotencyKey === "string" ? String(input.idempotencyKey).trim() : "";
|
|
63
|
-
return providedIdempotencyKey
|
|
62
|
+
return providedIdempotencyKey;
|
|
64
63
|
};
|
|
65
64
|
var withIdempotencyKey = (input) => {
|
|
66
65
|
const idempotencyKey = resolveIdempotencyKey(input);
|
|
67
66
|
if (!idempotencyKey) return input;
|
|
68
|
-
|
|
67
|
+
return {
|
|
69
68
|
...input,
|
|
70
69
|
idempotencyKey
|
|
71
70
|
};
|
|
72
|
-
delete next.eventKey;
|
|
73
|
-
return next;
|
|
74
71
|
};
|
|
75
72
|
var createLogger = (logLevel) => {
|
|
76
73
|
const shouldLog = (level) => logLevel !== "none" && LOG_LEVELS[level] <= LOG_LEVELS[logLevel];
|
|
@@ -145,6 +142,22 @@ var throwRequestError = (log, error, response, context) => {
|
|
|
145
142
|
log.error("Request failed", { context, status: response?.status, error });
|
|
146
143
|
throw new PriceOSError(getErrorMessage(error), { status: response?.status, details: error });
|
|
147
144
|
};
|
|
145
|
+
var resolveUrlResponse = (data, response) => {
|
|
146
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
147
|
+
const value = data.url;
|
|
148
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
149
|
+
return { url: value };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const location = response?.headers.get("location");
|
|
153
|
+
if (location && location.trim().length > 0) {
|
|
154
|
+
return { url: location };
|
|
155
|
+
}
|
|
156
|
+
if (response?.redirected && typeof response.url === "string" && response.url.trim().length > 0) {
|
|
157
|
+
return { url: response.url };
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
};
|
|
148
161
|
var createRetryingFetch = (baseFetch, log) => {
|
|
149
162
|
return async (input, init) => {
|
|
150
163
|
const { method, url } = getRequestDetails(input, init);
|
|
@@ -308,7 +321,43 @@ var PriceOS = class {
|
|
|
308
321
|
if (error) {
|
|
309
322
|
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/customer_portal");
|
|
310
323
|
}
|
|
311
|
-
|
|
324
|
+
if (response && !response.ok) {
|
|
325
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
326
|
+
}
|
|
327
|
+
const result = resolveUrlResponse(data, response);
|
|
328
|
+
if (result) {
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
throw new PriceOSError("Invalid customer portal response", {
|
|
332
|
+
status: response?.status,
|
|
333
|
+
details: {
|
|
334
|
+
redirected: response?.redirected ?? false,
|
|
335
|
+
responseUrl: response?.url ?? null
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
},
|
|
339
|
+
createCheckout: async (customerId, input) => {
|
|
340
|
+
const { data, error, response } = await this.client.POST("/v1/customers/{customerId}/checkout", {
|
|
341
|
+
params: { path: { customerId }, header: this.header },
|
|
342
|
+
body: input
|
|
343
|
+
});
|
|
344
|
+
if (error) {
|
|
345
|
+
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/checkout");
|
|
346
|
+
}
|
|
347
|
+
if (response && !response.ok) {
|
|
348
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
349
|
+
}
|
|
350
|
+
const result = resolveUrlResponse(data, response);
|
|
351
|
+
if (result) {
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
throw new PriceOSError("Invalid checkout response", {
|
|
355
|
+
status: response?.status,
|
|
356
|
+
details: {
|
|
357
|
+
redirected: response?.redirected ?? false,
|
|
358
|
+
responseUrl: response?.url ?? null
|
|
359
|
+
}
|
|
360
|
+
});
|
|
312
361
|
}
|
|
313
362
|
};
|
|
314
363
|
const getFeatureAccessForCustomer = async (customerId) => {
|
|
@@ -346,7 +395,20 @@ var PriceOS = class {
|
|
|
346
395
|
body: input
|
|
347
396
|
});
|
|
348
397
|
if (error) throwRequestError(this.log, error, response, "POST /v1/checkout");
|
|
349
|
-
|
|
398
|
+
if (response && !response.ok) {
|
|
399
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
400
|
+
}
|
|
401
|
+
const result = resolveUrlResponse(data, response);
|
|
402
|
+
if (result) {
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
throw new PriceOSError("Invalid checkout response", {
|
|
406
|
+
status: response?.status,
|
|
407
|
+
details: {
|
|
408
|
+
redirected: response?.redirected ?? false,
|
|
409
|
+
responseUrl: response?.url ?? null
|
|
410
|
+
}
|
|
411
|
+
});
|
|
350
412
|
}
|
|
351
413
|
};
|
|
352
414
|
this.bonuses = {
|
|
@@ -408,24 +470,6 @@ var PriceOS = class {
|
|
|
408
470
|
if (error) throwRequestError(this.log, error, response, "GET /v1/usage/{id}");
|
|
409
471
|
return data;
|
|
410
472
|
},
|
|
411
|
-
getEventByIdempotencyKey: async (idempotencyKey) => {
|
|
412
|
-
const { data, error, response } = await this.client.GET("/v1/usage/idempotency-key/{idempotencyKey}", {
|
|
413
|
-
params: { header: this.header, path: { idempotencyKey } }
|
|
414
|
-
});
|
|
415
|
-
if (error) {
|
|
416
|
-
throwRequestError(this.log, error, response, "GET /v1/usage/idempotency-key/{idempotencyKey}");
|
|
417
|
-
}
|
|
418
|
-
return data;
|
|
419
|
-
},
|
|
420
|
-
getEventByKey: async (eventKey) => {
|
|
421
|
-
const { data, error, response } = await this.client.GET("/v1/usage/idempotency-key/{idempotencyKey}", {
|
|
422
|
-
params: { header: this.header, path: { idempotencyKey: eventKey } }
|
|
423
|
-
});
|
|
424
|
-
if (error) {
|
|
425
|
-
throwRequestError(this.log, error, response, "GET /v1/usage/idempotency-key/{idempotencyKey}");
|
|
426
|
-
}
|
|
427
|
-
return data;
|
|
428
|
-
},
|
|
429
473
|
updateEvent: async (input) => {
|
|
430
474
|
const { id, ...body } = input;
|
|
431
475
|
const { data, error, response } = await this.client.PUT("/v1/usage/{id}", {
|
|
@@ -490,6 +534,7 @@ var FEATURE_ACCESS_PATH = "v1/feature-access";
|
|
|
490
534
|
var TRACK_USAGE_PATH = "v1/usage";
|
|
491
535
|
var PRICING_TABLE_PATH = "v1/pricing-table";
|
|
492
536
|
var CHECKOUT_PATH = "v1/checkout";
|
|
537
|
+
var CUSTOMER_PORTAL_PATH = "v1/customer-portal";
|
|
493
538
|
var normalizePath = (value) => value.replace(/^\/+/, "");
|
|
494
539
|
var logTrackUsageError = (message, details) => {
|
|
495
540
|
if (details === void 0) {
|
|
@@ -530,7 +575,7 @@ var parseTrackUsageBody = async (request) => {
|
|
|
530
575
|
if (!Number.isFinite(amount) || amount <= 0) {
|
|
531
576
|
return { error: "amount must be a positive number" };
|
|
532
577
|
}
|
|
533
|
-
const idempotencyKeyRaw = body.idempotencyKey
|
|
578
|
+
const idempotencyKeyRaw = body.idempotencyKey;
|
|
534
579
|
const idempotencyKey = idempotencyKeyRaw === void 0 ? void 0 : typeof idempotencyKeyRaw === "string" && idempotencyKeyRaw.trim().length > 0 ? idempotencyKeyRaw.trim() : null;
|
|
535
580
|
if (idempotencyKey === null) {
|
|
536
581
|
return { error: "idempotencyKey must be a non-empty string" };
|
|
@@ -595,13 +640,20 @@ var parseCheckoutBody = async (request) => {
|
|
|
595
640
|
return { error: "Invalid JSON body" };
|
|
596
641
|
}
|
|
597
642
|
const body = rawBody;
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
643
|
+
const stripeProductKey = typeof body.stripeProductKey === "string" && body.stripeProductKey.trim().length > 0 ? body.stripeProductKey.trim() : void 0;
|
|
644
|
+
const stripePriceId = typeof body.stripePriceId === "string" && body.stripePriceId.trim().length > 0 ? body.stripePriceId.trim() : void 0;
|
|
645
|
+
if (!stripeProductKey && !stripePriceId) {
|
|
646
|
+
return { error: "stripeProductKey or stripePriceId is required" };
|
|
647
|
+
}
|
|
648
|
+
const successUrlRaw = body.successUrl;
|
|
649
|
+
if (successUrlRaw !== void 0 && typeof successUrlRaw !== "string") {
|
|
650
|
+
return { error: "successUrl must be a non-empty string" };
|
|
601
651
|
}
|
|
602
|
-
const successUrl =
|
|
603
|
-
|
|
604
|
-
|
|
652
|
+
const successUrl = normalizeCustomerId(
|
|
653
|
+
typeof successUrlRaw === "string" ? successUrlRaw : void 0
|
|
654
|
+
);
|
|
655
|
+
if (successUrlRaw !== void 0 && !successUrl) {
|
|
656
|
+
return { error: "successUrl must be a non-empty string" };
|
|
605
657
|
}
|
|
606
658
|
const cancelUrl = typeof body.cancelUrl === "string" && body.cancelUrl.trim().length > 0 ? body.cancelUrl.trim() : void 0;
|
|
607
659
|
const customerId = typeof body.customerId === "string" && body.customerId.trim().length > 0 ? body.customerId.trim() : void 0;
|
|
@@ -616,16 +668,71 @@ var parseCheckoutBody = async (request) => {
|
|
|
616
668
|
}
|
|
617
669
|
}
|
|
618
670
|
}
|
|
671
|
+
const checkoutParamsRaw = body.checkoutParams;
|
|
672
|
+
if (checkoutParamsRaw !== void 0 && (!checkoutParamsRaw || typeof checkoutParamsRaw !== "object" || Array.isArray(checkoutParamsRaw))) {
|
|
673
|
+
return { error: "checkoutParams must be an object" };
|
|
674
|
+
}
|
|
675
|
+
const customerInfoRaw = body.customerInfo;
|
|
676
|
+
if (customerInfoRaw !== void 0 && (!customerInfoRaw || typeof customerInfoRaw !== "object" || Array.isArray(customerInfoRaw))) {
|
|
677
|
+
return { error: "customerInfo must be an object" };
|
|
678
|
+
}
|
|
679
|
+
const customerInfoRecord = customerInfoRaw;
|
|
680
|
+
const customerName = normalizeCustomerId(
|
|
681
|
+
typeof customerInfoRecord?.name === "string" ? customerInfoRecord.name : void 0
|
|
682
|
+
);
|
|
683
|
+
const customerEmail = normalizeCustomerId(
|
|
684
|
+
typeof customerInfoRecord?.email === "string" ? customerInfoRecord.email : void 0
|
|
685
|
+
);
|
|
619
686
|
return {
|
|
620
687
|
data: {
|
|
621
|
-
|
|
622
|
-
|
|
688
|
+
...stripeProductKey ? { stripeProductKey } : {},
|
|
689
|
+
...stripePriceId ? { stripePriceId } : {},
|
|
690
|
+
...successUrl ? { successUrl } : {},
|
|
623
691
|
...cancelUrl ? { cancelUrl } : {},
|
|
624
692
|
...customerId ? { customerId } : {},
|
|
625
|
-
...metadataRaw ? { metadata: metadataRaw } : {}
|
|
693
|
+
...metadataRaw ? { metadata: metadataRaw } : {},
|
|
694
|
+
...checkoutParamsRaw ? { checkoutParams: checkoutParamsRaw } : {},
|
|
695
|
+
...customerInfoRaw ? {
|
|
696
|
+
customerInfo: {
|
|
697
|
+
...customerName ? { name: customerName } : {},
|
|
698
|
+
...customerEmail ? { email: customerEmail } : {}
|
|
699
|
+
}
|
|
700
|
+
} : {}
|
|
626
701
|
}
|
|
627
702
|
};
|
|
628
703
|
};
|
|
704
|
+
var parseCustomerPortalBody = async (request) => {
|
|
705
|
+
let rawText = "";
|
|
706
|
+
try {
|
|
707
|
+
rawText = await request.text();
|
|
708
|
+
} catch {
|
|
709
|
+
return { error: "Invalid JSON body" };
|
|
710
|
+
}
|
|
711
|
+
if (!rawText.trim()) return { data: {} };
|
|
712
|
+
let rawBody;
|
|
713
|
+
try {
|
|
714
|
+
rawBody = JSON.parse(rawText);
|
|
715
|
+
} catch {
|
|
716
|
+
return { error: "Invalid JSON body" };
|
|
717
|
+
}
|
|
718
|
+
if (!rawBody || typeof rawBody !== "object" || Array.isArray(rawBody)) {
|
|
719
|
+
return { error: "Invalid JSON body" };
|
|
720
|
+
}
|
|
721
|
+
const body = rawBody;
|
|
722
|
+
const customerIdRaw = body.customerId;
|
|
723
|
+
if (customerIdRaw !== void 0 && typeof customerIdRaw !== "string") {
|
|
724
|
+
return { error: "customerId must be a non-empty string" };
|
|
725
|
+
}
|
|
726
|
+
const customerId = normalizeCustomerId(
|
|
727
|
+
typeof customerIdRaw === "string" ? customerIdRaw : void 0
|
|
728
|
+
);
|
|
729
|
+
if (customerIdRaw !== void 0 && !customerId) {
|
|
730
|
+
return { error: "customerId must be a non-empty string" };
|
|
731
|
+
}
|
|
732
|
+
return {
|
|
733
|
+
data: customerId ? { customerId } : {}
|
|
734
|
+
};
|
|
735
|
+
};
|
|
629
736
|
var handleGetCustomer = async (request, url, client, getCustomerId) => {
|
|
630
737
|
if (request.method.toUpperCase() !== "GET") {
|
|
631
738
|
return new Response("Method not allowed.", { status: 405 });
|
|
@@ -769,12 +876,79 @@ var handleCreateCheckout = async (request, client, getCustomerId) => {
|
|
|
769
876
|
request
|
|
770
877
|
);
|
|
771
878
|
if (errorResponse) return errorResponse;
|
|
879
|
+
if (parsed.data.customerId && resolvedCustomerId && parsed.data.customerId !== resolvedCustomerId) {
|
|
880
|
+
return jsonResponse(403, { error: "customerId must match authenticated customer" });
|
|
881
|
+
}
|
|
882
|
+
const customerId = parsed.data.customerId ?? resolvedCustomerId;
|
|
883
|
+
if (!customerId) {
|
|
884
|
+
return jsonResponse(401, { error: "Customer not identified" });
|
|
885
|
+
}
|
|
886
|
+
if (parsed.data.stripePriceId) {
|
|
887
|
+
const requestOrigin = new URL(request.url).origin;
|
|
888
|
+
const successUrl = parsed.data.successUrl ?? `${requestOrigin}/settings/billing?checkout=success`;
|
|
889
|
+
const cancelUrl = parsed.data.cancelUrl ?? successUrl;
|
|
890
|
+
try {
|
|
891
|
+
const data = await client.checkout.create({
|
|
892
|
+
stripePriceId: parsed.data.stripePriceId,
|
|
893
|
+
successUrl,
|
|
894
|
+
cancelUrl,
|
|
895
|
+
...parsed.data.metadata ? { metadata: parsed.data.metadata } : {},
|
|
896
|
+
customerId
|
|
897
|
+
});
|
|
898
|
+
return jsonResponse(200, data);
|
|
899
|
+
} catch (error) {
|
|
900
|
+
if (error instanceof PriceOSError) {
|
|
901
|
+
return jsonResponse(error.status ?? 500, { error: error.message });
|
|
902
|
+
}
|
|
903
|
+
return jsonResponse(500, { error: "Request failed" });
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (!parsed.data.stripeProductKey) {
|
|
907
|
+
return jsonResponse(400, { error: "stripeProductKey is required" });
|
|
908
|
+
}
|
|
909
|
+
const checkoutParams = {
|
|
910
|
+
...parsed.data.checkoutParams ?? {},
|
|
911
|
+
...parsed.data.cancelUrl ? { cancel_url: parsed.data.cancelUrl } : {},
|
|
912
|
+
...parsed.data.metadata ? { metadata: parsed.data.metadata } : {}
|
|
913
|
+
};
|
|
772
914
|
const body = {
|
|
773
|
-
|
|
774
|
-
...parsed.data.
|
|
915
|
+
stripeProductKey: parsed.data.stripeProductKey,
|
|
916
|
+
...parsed.data.successUrl ? { successUrl: parsed.data.successUrl } : {},
|
|
917
|
+
...parsed.data.customerInfo ? { customerInfo: parsed.data.customerInfo } : {},
|
|
918
|
+
...Object.keys(checkoutParams).length ? { checkoutParams } : {}
|
|
775
919
|
};
|
|
776
920
|
try {
|
|
777
|
-
const data = await client.
|
|
921
|
+
const data = await client.customers.createCheckout(customerId, body);
|
|
922
|
+
return jsonResponse(200, data);
|
|
923
|
+
} catch (error) {
|
|
924
|
+
if (error instanceof PriceOSError) {
|
|
925
|
+
return jsonResponse(error.status ?? 500, { error: error.message });
|
|
926
|
+
}
|
|
927
|
+
return jsonResponse(500, { error: "Request failed" });
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
var handleCreateCustomerPortal = async (request, client, getCustomerId) => {
|
|
931
|
+
if (request.method.toUpperCase() !== "POST") {
|
|
932
|
+
return new Response("Method not allowed.", { status: 405 });
|
|
933
|
+
}
|
|
934
|
+
const parsed = await parseCustomerPortalBody(request);
|
|
935
|
+
if (!parsed.data) {
|
|
936
|
+
return jsonResponse(400, { error: parsed.error ?? "Invalid request body" });
|
|
937
|
+
}
|
|
938
|
+
const { customerId: resolvedCustomerId, errorResponse } = await resolveOptionalCustomerId(
|
|
939
|
+
getCustomerId,
|
|
940
|
+
request
|
|
941
|
+
);
|
|
942
|
+
if (errorResponse) return errorResponse;
|
|
943
|
+
if (parsed.data.customerId && resolvedCustomerId && parsed.data.customerId !== resolvedCustomerId) {
|
|
944
|
+
return jsonResponse(403, { error: "customerId must match authenticated customer" });
|
|
945
|
+
}
|
|
946
|
+
const customerId = parsed.data.customerId ?? resolvedCustomerId;
|
|
947
|
+
if (!customerId) {
|
|
948
|
+
return jsonResponse(401, { error: "Customer not identified" });
|
|
949
|
+
}
|
|
950
|
+
try {
|
|
951
|
+
const data = await client.customers.createPortal(customerId);
|
|
778
952
|
return jsonResponse(200, data);
|
|
779
953
|
} catch (error) {
|
|
780
954
|
if (error instanceof PriceOSError) {
|
|
@@ -823,6 +997,9 @@ function priceosHandler(options = {}) {
|
|
|
823
997
|
if (path === CHECKOUT_PATH) {
|
|
824
998
|
return handleCreateCheckout(request, client, getCustomerId);
|
|
825
999
|
}
|
|
1000
|
+
if (path === CUSTOMER_PORTAL_PATH) {
|
|
1001
|
+
return handleCreateCustomerPortal(request, client, getCustomerId);
|
|
1002
|
+
}
|
|
826
1003
|
return new Response("Not found.", { status: 404 });
|
|
827
1004
|
};
|
|
828
1005
|
return Object.assign(handler, {
|