@remcostoeten/fync
Version:
Unified TypeScript library for 9 popular APIs with consistent functional architecture
321 lines (320 loc) • 8.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Vercel = Vercel;
var _core = require("../core");
const VERCEL_API_BASE = "https://api.vercel.com";
const projectResource = (0, _core.defineResource)({
name: "projects",
basePath: "/v9/projects",
methods: {
listProjects: {
path: ""
},
getProject: {
path: "/{projectId}"
},
createProject: {
path: "",
method: "POST"
},
updateProject: {
path: "/{projectId}",
method: "PATCH"
},
deleteProject: {
path: "/{projectId}",
method: "DELETE"
},
getProjectDomains: {
path: "/{projectId}/domains"
},
getProjectEnvVars: {
path: "/{projectId}/env"
},
createProjectEnvVar: {
path: "/{projectId}/env",
method: "POST"
}
}
});
const deploymentResource = (0, _core.defineResource)({
name: "deployments",
basePath: "/v13/deployments",
methods: {
listDeployments: {
path: ""
},
getDeployment: {
path: "/{deploymentId}"
},
deleteDeployment: {
path: "/{deploymentId}",
method: "DELETE"
},
getDeploymentEvents: {
path: "/{deploymentId}/events"
},
getDeploymentFiles: {
path: "/{deploymentId}/files"
},
cancelDeployment: {
path: "/{deploymentId}/cancel",
method: "PATCH"
}
}
});
const domainResource = (0, _core.defineResource)({
name: "domains",
basePath: "/v5/domains",
methods: {
listDomains: {
path: ""
},
getDomain: {
path: "/{domain}"
},
addDomain: {
path: "",
method: "POST"
},
removeDomain: {
path: "/{domain}",
method: "DELETE"
},
verifyDomain: {
path: "/{domain}/verify",
method: "POST"
},
getDomainConfig: {
path: "/{domain}/config"
}
}
});
const teamResource = (0, _core.defineResource)({
name: "teams",
basePath: "/v2/teams",
methods: {
listTeams: {
path: ""
},
getTeam: {
path: "/{teamId}"
},
createTeam: {
path: "",
method: "POST"
},
updateTeam: {
path: "/{teamId}",
method: "PATCH"
},
deleteTeam: {
path: "/{teamId}",
method: "DELETE"
},
getTeamMembers: {
path: "/{teamId}/members"
},
inviteTeamMember: {
path: "/{teamId}/members",
method: "POST"
}
}
});
const userResource = (0, _core.defineResource)({
name: "user",
basePath: "/v2/user",
methods: {
getUser: {
path: ""
},
updateUser: {
path: "",
method: "PATCH"
},
deleteUser: {
path: "",
method: "DELETE"
},
getUserEvents: {
path: "/events"
},
getUserTokens: {
path: "/tokens"
}
}
});
const resources = {
projects: projectResource,
deployments: deploymentResource,
domains: domainResource,
teams: teamResource,
user: userResource
};
const buildVercel = (0, _core.createApiBuilder)({
baseUrl: VERCEL_API_BASE,
auth: {
type: "bearer"
},
headers: {
"Content-Type": "application/json"
}
});
function Vercel(config) {
const apiConfig = {
token: config.token,
headers: config.teamId ? {
"x-vercel-team-id": config.teamId
} : undefined
};
const base = buildVercel(apiConfig, resources);
const vercel = base;
vercel.getProject = function (projectId) {
return base.projects.getProject({
projectId
});
};
vercel.listProjects = function (teamId) {
const params = {};
if (teamId) params.teamId = teamId;
return base.projects.listProjects(params);
};
vercel.getLatestDeployment = async function (projectId) {
const deployments = await base.deployments.listDeployments({
projectId,
limit: 1
});
return deployments[0] || null;
};
vercel.getDeploymentStatus = async function (deploymentId) {
const deployment = await base.deployments.getDeployment({
deploymentId
});
return {
id: deployment.id,
state: deployment.state,
ready: deployment.ready,
url: deployment.url,
createdAt: deployment.createdAt
};
};
vercel.redeployProject = async function (projectId) {
const latest = await vercel.getLatestDeployment(projectId);
if (!latest) throw new Error("No deployments found");
return base.deployments.createDeployment({
name: latest.name,
project: projectId,
gitSource: latest.gitSource
});
};
vercel.getProjectAnalytics = async function (projectId, options) {
// Vercel Analytics API endpoint
// Note: This requires the project to have analytics enabled
const period = options?.period || "7d";
const from = options?.from || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const to = options?.to || new Date().toISOString();
try {
// Get project details
const project = await base.projects.getProject({
projectId
});
// Analytics data is available through a separate endpoint
// The actual analytics API requires special permissions and may vary
const analyticsResponse = await fetch(`https://api.vercel.com/v1/analytics/projects/${projectId}`, {
headers: {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json"
},
method: "GET"
});
if (!analyticsResponse.ok) {
// Fallback to Web Analytics API if available
const webAnalyticsResponse = await fetch(`https://api.vercel.com/v1/web/analytics/${projectId}?from=${from}&to=${to}&limit=100`, {
headers: {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json"
},
method: "GET"
});
if (webAnalyticsResponse.ok) {
const webAnalytics = await webAnalyticsResponse.json();
return {
project,
analytics: {
period,
data: webAnalytics,
visits: webAnalytics.total?.visits || 0,
uniqueVisitors: webAnalytics.total?.uniqueVisitors || 0,
pageViews: webAnalytics.total?.pageViews || 0,
avgDuration: webAnalytics.total?.avgDuration || 0,
bounceRate: webAnalytics.total?.bounceRate || 0
}
};
}
// If analytics are not available, return basic project metrics
return {
project,
analytics: {
period,
message: "Analytics not available for this project. Ensure analytics is enabled.",
visits: null,
uniqueVisitors: null
}
};
}
const analyticsData = await analyticsResponse.json();
return {
project,
analytics: {
period,
data: analyticsData,
visits: analyticsData.visits || 0,
uniqueVisitors: analyticsData.uniqueVisitors || 0,
pageViews: analyticsData.pageViews || 0,
avgDuration: analyticsData.avgDuration || 0,
bounceRate: analyticsData.bounceRate || 0
}
};
} catch (error) {
// Handle error gracefully
const project = await base.projects.getProject({
projectId
});
return {
project,
analytics: {
period,
error: error instanceof Error ? error.message : "Failed to fetch analytics",
visits: null,
uniqueVisitors: null
}
};
}
};
vercel.getDomainStatus = async function (domain) {
const domainInfo = await base.domains.getDomain({
domain
});
return {
domain: domainInfo.name,
verified: domainInfo.verified,
configured: domainInfo.configured,
expires: domainInfo.expiresAt
};
};
vercel.getTeamUsage = async function (teamId) {
const team = await base.teams.getTeam({
teamId
});
return {
team: team.name,
usage: {
projects: team.projectsCount || 0,
members: team.membersCount || 0
}
};
};
return vercel;
}