autumn-js
Version:
Autumn JS Library
872 lines (850 loc) • 21.2 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/libraries/backend/react-router.ts
var react_router_exports = {};
__export(react_router_exports, {
autumnHandler: () => autumnHandler
});
module.exports = __toCommonJS(react_router_exports);
var import_rou35 = require("rou3");
// src/sdk/error.ts
var AutumnError = class extends Error {
message;
code;
constructor(response) {
super(response.message);
this.message = response.message;
this.code = response.code;
}
toString() {
return `${this.message} (code: ${this.code})`;
}
toJSON() {
return {
message: this.message,
code: this.code
};
}
};
// src/sdk/utils.ts
var staticWrapper = (callback, instance, args) => {
if (!instance) {
instance = new Autumn();
}
return callback({ instance, ...args });
};
// src/sdk/customers/cusMethods.ts
var customerMethods = (instance) => {
return {
get: (id, params) => staticWrapper(getCustomer, instance, { id, params }),
create: (params) => staticWrapper(createCustomer, instance, { params }),
update: (id, params) => staticWrapper(updateCustomer, instance, { id, params }),
delete: (id) => staticWrapper(deleteCustomer, instance, { id }),
billingPortal: (id, params) => staticWrapper(billingPortal, instance, { id, params })
};
};
var getExpandStr = (expand) => {
if (!expand) {
return "";
}
return `expand=${expand.join(",")}`;
};
var getCustomer = async ({
instance,
id,
params
}) => {
if (!id) {
return {
data: null,
error: new AutumnError({
message: "Customer ID is required",
code: "CUSTOMER_ID_REQUIRED"
})
};
}
return instance.get(`/customers/${id}?${getExpandStr(params?.expand)}`);
};
var createCustomer = async ({
instance,
params
}) => {
return instance.post(`/customers?${getExpandStr(params?.expand)}`, params);
};
var updateCustomer = async ({
instance,
id,
params
}) => {
return instance.post(`/customers/${id}`, params);
};
var deleteCustomer = async ({
instance,
id
}) => {
return instance.delete(`/customers/${id}`);
};
var billingPortal = async ({
instance,
id,
params
}) => {
return instance.post(`/customers/${id}/billing_portal`, params);
};
// src/sdk/customers/entities/entMethods.ts
var entityMethods = (instance) => {
return {
get: (customer_id, entity_id, params) => staticWrapper(getEntity, instance, {
customer_id,
entity_id,
params
}),
create: (customer_id, params) => staticWrapper(createEntity, instance, { customer_id, params }),
delete: (customer_id, entity_id) => staticWrapper(deleteEntity, instance, { customer_id, entity_id })
};
};
var getExpandStr2 = (expand) => {
if (!expand) {
return "";
}
return `expand=${expand.join(",")}`;
};
var getEntity = async ({
instance,
customer_id,
entity_id,
params
}) => {
return instance.get(
`/customers/${customer_id}/entities/${entity_id}?${getExpandStr2(
params?.expand
)}`
);
};
var createEntity = async ({
instance,
customer_id,
params
}) => {
return instance.post(`/customers/${customer_id}/entities`, params);
};
var deleteEntity = async ({
instance,
customer_id,
entity_id
}) => {
return instance.delete(`/customers/${customer_id}/entities/${entity_id}`);
};
// src/sdk/general/genMethods.ts
var handleAttach = async ({
instance,
params
}) => {
return instance.post("/attach", params);
};
var handleCancel = async ({
instance,
params
}) => {
return instance.post("/cancel", params);
};
var handleEntitled = async ({
instance,
params
}) => {
return instance.post("/entitled", params);
};
var handleEvent = async ({
instance,
params
}) => {
return instance.post("/events", params);
};
var handleTrack = async ({
instance,
params
}) => {
return instance.post("/track", params);
};
var handleUsage = async ({
instance,
params
}) => {
return instance.post("/usage", params);
};
var handleCheck = async ({
instance,
params
}) => {
return instance.post("/check", params);
};
// src/sdk/products/prodMethods.ts
var productMethods = (instance) => {
return {
get: (id) => staticWrapper(getProduct, instance, { id }),
create: (params) => staticWrapper(createProduct, instance, { params }),
list: (params) => staticWrapper(listProducts, instance, { params })
};
};
var listProducts = async ({
instance,
params
}) => {
let path = "/products";
if (params) {
const queryParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== void 0) {
queryParams.append(key, String(value));
}
}
const queryString = queryParams.toString();
if (queryString) {
path += `?${queryString}`;
}
}
return instance.get(path);
};
var getProduct = async ({
instance,
id
}) => {
return instance.get(`/products/${id}`);
};
var createProduct = async ({
instance,
params
}) => {
return instance.post("/products", params);
};
// src/sdk/referrals/referralMethods.ts
var referralMethods = (instance) => {
return {
createCode: (params) => staticWrapper(createReferralCode, instance, { params }),
redeemCode: (params) => staticWrapper(redeemReferralCode, instance, { params })
};
};
var createReferralCode = async ({
instance,
params
}) => {
return instance.post("/referrals/code", params);
};
var redeemReferralCode = async ({
instance,
params
}) => {
return instance.post("/referrals/redeem", params);
};
// src/sdk/response.ts
var toContainerResult = async (response) => {
if (response.status < 200 || response.status >= 300) {
let error;
try {
error = await response.json();
} catch (error2) {
return {
data: null,
error: new AutumnError({
message: "Failed to parse JSON response from Autumn",
code: "internal_error"
}),
statusCode: response.status
};
}
return {
data: null,
error: new AutumnError({
message: error.message,
code: error.code
}),
statusCode: response.status
};
}
try {
let data = await response.json();
return {
data,
error: null,
statusCode: response?.status
};
} catch (error) {
return {
data: null,
error: new AutumnError({
message: "Failed to parse Autumn API response",
code: "internal_error"
}),
statusCode: response?.status
};
}
};
// src/sdk/client.ts
var LATEST_API_VERSION = "1.2";
var Autumn = class {
secretKey;
publishableKey;
level;
headers;
url;
constructor(options) {
try {
this.secretKey = options?.secretKey || process.env.AUTUMN_SECRET_KEY;
this.publishableKey = options?.publishableKey || process.env.AUTUMN_PUBLISHABLE_KEY;
} catch (error) {
}
if (!this.secretKey && !this.publishableKey && !options?.headers) {
throw new Error("Autumn secret key or publishable key is required");
}
this.headers = options?.headers || {
Authorization: `Bearer ${this.secretKey || this.publishableKey}`,
"Content-Type": "application/json"
};
let version = options?.version || LATEST_API_VERSION;
this.headers["x-api-version"] = version;
this.url = options?.url || "https://api.useautumn.com/v1";
this.level = this.secretKey ? "secret" : "publishable";
}
getLevel() {
return this.level;
}
async get(path) {
const response = await fetch(`${this.url}${path}`, {
headers: this.headers
});
return toContainerResult(response);
}
async post(path, body) {
try {
const response = await fetch(`${this.url}${path}`, {
method: "POST",
headers: this.headers,
body: JSON.stringify(body)
});
return toContainerResult(response);
} catch (error) {
console.error("Error sending request:", error);
throw error;
}
}
async delete(path) {
const response = await fetch(`${this.url}${path}`, {
method: "DELETE",
headers: this.headers
});
return toContainerResult(response);
}
static customers = customerMethods();
static products = productMethods();
static entities = entityMethods();
static referrals = referralMethods();
customers = customerMethods(this);
products = productMethods(this);
entities = entityMethods(this);
referrals = referralMethods(this);
static attach = (params) => staticWrapper(handleAttach, void 0, { params });
static usage = (params) => staticWrapper(handleUsage, void 0, { params });
async attach(params) {
return handleAttach({
instance: this,
params
});
}
static cancel = (params) => staticWrapper(handleCancel, void 0, { params });
async cancel(params) {
return handleCancel({
instance: this,
params
});
}
/**
* @deprecated This method is deprecated and will be removed in a future version.
* Please use the new check() method instead.
*/
static entitled = (params) => staticWrapper(handleEntitled, void 0, { params });
/**
* @deprecated This method is deprecated and will be removed in a future version.
* Please use the new check() method instead.
*/
async entitled(params) {
return handleEntitled({
instance: this,
params
});
}
static check = (params) => staticWrapper(handleCheck, void 0, { params });
async check(params) {
return handleCheck({
instance: this,
params
});
}
/**
* @deprecated This method is deprecated and will be removed in a future version.
* Please use the new track() method instead.
*/
static event = (params) => staticWrapper(handleEvent, void 0, { params });
/**
* @deprecated This method is deprecated and will be removed in a future version.
* Please use the new track() method instead.
*/
async event(params) {
return handleEvent({
instance: this,
params
});
}
static track = (params) => staticWrapper(handleTrack, void 0, { params });
async track(params) {
return handleTrack({
instance: this,
params
});
}
async usage(params) {
return handleUsage({
instance: this,
params
});
}
};
// src/sdk/components/componentMethods.ts
var fetchPricingTable = async ({
instance,
params
}) => {
let path = "/components/pricing_table";
if (params) {
const queryParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (key === "products") {
continue;
}
if (value !== void 0) {
queryParams.append(key, String(value));
}
}
const queryString = queryParams.toString();
if (queryString) {
path += `?${queryString}`;
}
}
return await instance.get(path);
};
// src/libraries/backend/utils/backendRes.ts
var toBackendRes = ({ res }) => {
let statusCode = res.statusCode ? res.statusCode : res.error ? 500 : 200;
return {
body: res.data ? res.data : res.error,
statusCode
};
};
var toBackendError = ({
path,
message,
code,
statusCode = 500
}) => {
console.error(
`Autumn middleware error: ${message} (code: ${code}) | path: ${path}`
);
return {
statusCode,
body: new AutumnError({
message: message || "Internal server error",
code: code || "internal_server_error"
})
};
};
// src/libraries/backend/utils/withAuth.ts
var withAuth = ({
fn,
requireCustomer = true
}) => {
return async ({
autumn,
body,
path,
getCustomer: getCustomer2,
pathParams,
searchParams
}) => {
let authResult = await getCustomer2();
let customerId = authResult?.customerId;
if (!customerId && requireCustomer) {
if (body?.errorOnNotFound === false) {
return toBackendError({
path,
message: "No customer ID found",
code: "no_customer_id",
statusCode: 202
});
} else {
return toBackendError({
path,
message: "No customer ID found",
code: "no_customer_id",
statusCode: 401
});
}
}
let cusData = authResult?.customerData || body?.customer_data;
try {
let res = await fn({
body,
autumn,
customer_id: customerId,
customer_data: cusData,
pathParams,
searchParams
});
return toBackendRes({ res });
} catch (error) {
return toBackendError({
path,
message: error.message || "unknown error",
code: "internal_error"
});
}
};
};
// src/libraries/backend/routes/genRoutes.ts
var import_rou3 = require("rou3");
// src/libraries/backend/constants.ts
var autumnApiUrl = "https://api.useautumn.com/v1";
var BASE_PATH = "/api/autumn";
// src/libraries/backend/routes/genRoutes.ts
var sanitizeBody = (body) => {
let bodyCopy = { ...body };
delete bodyCopy.customer_id;
delete bodyCopy.customer_data;
return bodyCopy;
};
var attachHandler = withAuth({
fn: async ({
autumn,
customer_id,
customer_data,
body
}) => {
return await autumn.attach({
...sanitizeBody(body),
customer_id,
customer_data
});
}
});
var cancelHandler = withAuth({
fn: async ({
autumn,
customer_id,
body
}) => {
return await autumn.cancel({
...sanitizeBody(body),
customer_id
});
}
});
var checkHandler = withAuth({
fn: async ({
autumn,
customer_id,
customer_data,
body
}) => {
const result = await autumn.check({
...sanitizeBody(body),
customer_id,
customer_data
});
return result;
}
});
var trackHandler = withAuth({
fn: async ({
autumn,
customer_id,
customer_data,
body
}) => {
return await autumn.track({
...sanitizeBody(body),
customer_id,
customer_data
});
}
});
var openBillingPortalHandler = withAuth({
fn: async ({
autumn,
customer_id,
body
}) => {
return await autumn.customers.billingPortal(customer_id, body);
}
});
var addGenRoutes = (router) => {
(0, import_rou3.addRoute)(router, "POST", `${BASE_PATH}/attach`, {
handler: attachHandler
});
(0, import_rou3.addRoute)(router, "POST", `${BASE_PATH}/cancel`, {
handler: cancelHandler
});
(0, import_rou3.addRoute)(router, "POST", `${BASE_PATH}/check`, {
handler: checkHandler
});
(0, import_rou3.addRoute)(router, "POST", `${BASE_PATH}/track`, {
handler: trackHandler
});
(0, import_rou3.addRoute)(router, "POST", `${BASE_PATH}/billing_portal`, {
handler: openBillingPortalHandler
});
};
// src/libraries/backend/routes/backendRouter.ts
var import_rou34 = require("rou3");
// src/libraries/backend/routes/entityRoutes.ts
var import_rou32 = require("rou3");
var createEntityHandler = withAuth({
fn: async ({
autumn,
customer_id,
body
}) => {
return await autumn.entities.create(customer_id, body);
}
});
var getEntityHandler = withAuth({
fn: async ({
autumn,
customer_id,
pathParams,
searchParams
}) => {
if (!pathParams?.entityId) {
return {
statusCode: 400,
body: {
error: "no_entity_id",
message: "Entity ID is required"
}
};
}
let params = {
expand: searchParams?.expand?.split(",")
};
let res = await autumn.entities.get(
customer_id,
pathParams.entityId,
params
);
return res;
}
});
var deleteEntityHandler = withAuth({
fn: async ({
autumn,
customer_id,
pathParams
}) => {
if (!pathParams?.entityId) {
return {
statusCode: 400,
body: {
error: "no_entity_id",
message: "Entity ID is required"
}
};
}
return await autumn.entities.delete(customer_id, pathParams.entityId);
}
});
var addEntityRoutes = async (router) => {
(0, import_rou32.addRoute)(router, "POST", "/api/autumn/entities", {
handler: createEntityHandler
});
(0, import_rou32.addRoute)(router, "GET", "/api/autumn/entities/:entityId", {
handler: getEntityHandler
});
(0, import_rou32.addRoute)(router, "DELETE", "/api/autumn/entities/:entityId", {
handler: deleteEntityHandler
});
};
// src/libraries/backend/routes/referralRoutes.ts
var import_rou33 = require("rou3");
var createReferralCodeHandler = withAuth({
fn: async ({
autumn,
customer_id,
body
}) => {
return await autumn.referrals.createCode({
...body,
customer_id
});
}
});
var redeemReferralCodeHandler = withAuth({
fn: async ({
autumn,
customer_id,
body
}) => {
return await autumn.referrals.redeemCode({
...body,
customer_id
});
}
});
var addReferralRoutes = async (router) => {
(0, import_rou33.addRoute)(router, "POST", `${BASE_PATH}/referrals/code`, {
handler: createReferralCodeHandler
});
(0, import_rou33.addRoute)(router, "POST", `${BASE_PATH}/referrals/redeem`, {
handler: redeemReferralCodeHandler
});
};
// src/libraries/backend/routes/backendRouter.ts
var sanitizeCustomerBody = (body) => {
let bodyCopy = { ...body };
delete bodyCopy.id;
delete bodyCopy.name;
delete bodyCopy.email;
return bodyCopy;
};
var createCustomerHandler = withAuth({
fn: async ({
autumn,
customer_id,
customer_data = {},
body
}) => {
let res = await autumn.customers.create({
id: customer_id,
...customer_data,
...sanitizeCustomerBody(body)
});
return res;
}
});
var getPricingTableHandler = withAuth({
fn: async ({
autumn,
customer_id
}) => {
return await fetchPricingTable({
instance: autumn,
params: {
customer_id: customer_id || void 0
}
});
},
requireCustomer: false
});
var createRouterWithOptions = () => {
const router = (0, import_rou34.createRouter)();
(0, import_rou34.addRoute)(router, "POST", `${BASE_PATH}/customers`, {
handler: createCustomerHandler
});
(0, import_rou34.addRoute)(router, "GET", `${BASE_PATH}/components/pricing_table`, {
handler: getPricingTableHandler,
requireCustomer: false
});
addGenRoutes(router);
addEntityRoutes(router);
addReferralRoutes(router);
return router;
};
// src/libraries/backend/react-router.ts
function autumnHandler(options) {
const autumn = new Autumn({
secretKey: options.secretKey || void 0,
url: autumnApiUrl
});
const router = createRouterWithOptions();
async function handleRequest(request, params = {}) {
const method = request.method;
const url = new URL(request.url);
const searchParams = Object.fromEntries(url.searchParams);
const pathname = url.pathname;
const match = (0, import_rou35.findRoute)(router, method, pathname);
if (!match) {
throw new Response("Not found", { status: 404 });
}
const { data, params: pathParams } = match;
const { handler } = data;
let body = null;
if (method === "POST" || method === "PUT" || method === "PATCH") {
try {
body = await request.json();
} catch (error) {
}
}
const result = await handler({
autumn,
body,
path: url.pathname,
getCustomer: async () => await options.identify({ request, params }),
pathParams: { ...pathParams, ...params },
searchParams
});
return new Response(JSON.stringify(result.body), {
status: result.statusCode,
headers: {
"Content-Type": "application/json"
}
});
}
async function loader({
request,
params
}) {
if (request.method !== "GET") {
throw new Response("Method not allowed", { status: 405 });
}
const response = await handleRequest(request, params);
const data = await response.json();
if (!response.ok) {
throw new Response(JSON.stringify(data), { status: response.status });
}
return data;
}
async function action({
request,
params
}) {
if (request.method === "GET") {
throw new Response("Method not allowed", { status: 405 });
}
const response = await handleRequest(request, params);
const data = await response.json();
if (!response.ok) {
throw new Response(JSON.stringify(data), { status: response.status });
}
return data;
}
return {
loader,
action
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
autumnHandler
});