Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { listen } from "./commands/listen";
import { login } from "./commands/login";
import { logout } from "./commands/logout";
import { migrate } from "./commands/migrate";
import { trigger } from "./commands/trigger";
import { whoami } from "./commands/whoami";
import { update } from "./commands/update";
import * as Migration from "./services/migration/migrate";
import * as OAuth from "./services/oauth";
Expand All @@ -18,6 +20,8 @@ const mainCommand = Command.make("polar").pipe(
logout,
migrate,
listen,
trigger,
whoami,
update
])
);
Expand Down
89 changes: 89 additions & 0 deletions src/commands/trigger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Args, Command } from "@effect/cli";
import { Effect } from "effect";
import { environmentPrompt } from "../prompts/environment";

const eventType = Args.text({ name: "event" });
const url = Args.text({ name: "url" });

const MOCK_PAYLOADS: Record<string, any> = {
"subscription.created": {
type: "subscription.created",
data: {
id: "sub_123456",
status: "active",
customer_id: "cus_abcdef",
product_id: "prod_pro_plan",
current_period_end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
}
},
"order.created": {
type: "order.created",
data: {
id: "ord_789012",
amount: 2000,
currency: "usd",
customer_id: "cus_abcdef",
product_id: "prod_digital_ebook",
}
},
"benefit.granted": {
type: "benefit.granted",
data: {
id: "ben_345678",
customer_id: "cus_abcdef",
benefit_type: "github_repository",
properties: {
repository_owner: "polarsource",
repository_name: "polar",
}
}
}
};

export const trigger = Command.make("trigger", { event: eventType, url }, ({ event, url }) =>
Effect.gen(function* () {
const environment = yield* environmentPrompt;

const payload = MOCK_PAYLOADS[event];
if (!payload) {
console.error(`\x1b[31mError:\x1b[0m Unknown event type '${event}'.`);
console.log("\x1b[2mAvailable events:\x1b[0m");
Object.keys(MOCK_PAYLOADS).forEach(e => console.log(` - ${e}`));
return;
}

const timestamp = Math.floor(Date.now() / 1000).toString();
const webhookId = `wh_mock_${Math.random().toString(36).substring(7)}`;

const headers = {
"user-agent": "polar.sh webhooks",
"content-type": "application/json",
"webhook-id": webhookId,
"webhook-timestamp": timestamp,
"webhook-signature": "mock_signature_for_local_testing",
};

const fullPayload = {
...payload,
timestamp: new Date().toISOString(),
};

console.log(`\x1b[36mTriggering\x1b[0m '${event}' to ${url}...`);

try {
const response = yield* Effect.promise(() => fetch(url, {
method: "POST",
headers,
body: JSON.stringify(fullPayload),
}));

if (response.ok) {
console.log(`\x1b[32mSuccess!\x1b[0m Webhook received with status ${response.status}`);
} else {
console.error(`\x1b[31mFailed:\x1b[0m Receiver returned ${response.status} ${response.statusText}`);
}
} catch (error) {
console.error(`\x1b[31mError:\x1b[0m Could not reach ${url}. Is your server running?`);
}
})
);
38 changes: 38 additions & 0 deletions src/commands/whoami.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Command } from "@effect/cli";
import { Effect } from "effect";
import { environmentPrompt } from "../prompts/environment";
import * as Polar from "../services/polar";

export const whoami = Command.make("whoami", {}, () =>
Effect.gen(function* () {
const environment = yield* environmentPrompt;
const polar = yield* Polar.Polar;

try {
const user = yield* polar.use((client) => client.users.getAuthenticated(), environment);
const organizations = yield* polar.use((client) => client.organizations.list({ limit: 100 }), environment);

const bold = "\x1b[1m";
const cyan = "\x1b[36m";
const reset = "\x1b[0m";
const dim = "\x1b[2m";

console.log("");
console.log(` ${bold}Logged in as:${reset} ${cyan}${user.email}${reset}`);
console.log(` ${bold}Environment:${reset} ${environment}`);
console.log("");

if (organizations.result.items.length > 0) {
console.log(` ${bold}Organizations:${reset}`);
organizations.result.items.forEach(org => {
console.log(` ${dim}•${reset} ${org.name} ${dim}(${org.slug})${reset}`);
});
} else {
console.log(` ${dim}No organizations found.${reset}`);
}
console.log("");
} catch (error) {
console.error("\x1b[31mError:\x1b[0m Not logged in or session expired. Run 'polar login' to authenticate.");
}
})
);