mirror of
https://github.com/LukeHagar/polar.git
synced 2025-12-06 04:20:58 +00:00
document api
This commit is contained in:
380
README.md
380
README.md
@@ -1,152 +1,66 @@
|
|||||||
# Convex Component Template
|
# Convex Polar Component
|
||||||
|
|
||||||
This is a Convex component, ready to be published on npm.
|
[](https://badge.fury.io/js/@convex-dev%2Fpolar)
|
||||||
|
|
||||||
To create your own component:
|
**Note: Convex Components are currently in beta.**
|
||||||
|
|
||||||
1. Find and replace "Counter" to your component's Name.
|
|
||||||
1. Find and replace "counter" to your component's name.
|
|
||||||
1. Write code in src/component for your component.
|
|
||||||
1. Write code in src/client for your thick client.
|
|
||||||
1. Write example usage in example/convex/example.ts.
|
|
||||||
1. Delete the text in this readme until `---` and flesh out the README.
|
|
||||||
|
|
||||||
It is safe to find & replace "counter" project-wide.
|
|
||||||
|
|
||||||
To develop your component run a dev process in the example project.
|
|
||||||
|
|
||||||
```
|
|
||||||
npm i
|
|
||||||
cd example
|
|
||||||
npm i
|
|
||||||
npx convex dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Modify the schema and index files in src/component/ to define your component.
|
|
||||||
|
|
||||||
Write a client for using this component in src/client/index.ts.
|
|
||||||
|
|
||||||
If you won't be adding frontend code (e.g. React components) to this
|
|
||||||
component you can delete the following:
|
|
||||||
|
|
||||||
- "prepack" and "postpack" scripts of package.json
|
|
||||||
- "./react" exports in package.json
|
|
||||||
- the "src/react/" directory
|
|
||||||
- the "node10stubs.mjs" file
|
|
||||||
|
|
||||||
### Component Directory structure
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── README.md documentation of your component
|
|
||||||
├── package.json component name, version number, other metadata
|
|
||||||
├── package-lock.json Components are like libraries, package-lock.json
|
|
||||||
│ is .gitignored and ignored by consumers.
|
|
||||||
├── src
|
|
||||||
│ ├── component/
|
|
||||||
│ │ ├── _generated/ Files here are generated.
|
|
||||||
│ │ ├── convex.config.ts Name your component here and use other components
|
|
||||||
│ │ ├── index.ts Define functions here and in new files in this directory
|
|
||||||
│ │ └── schema.ts schema specific to this component
|
|
||||||
│ ├── client/index.ts "Thick" client code goes here.
|
|
||||||
│ └── react/ Code intended to be used on the frontend goes here.
|
|
||||||
│ │ Your are free to delete this if this component
|
|
||||||
│ │ does not provide code.
|
|
||||||
│ └── index.ts
|
|
||||||
├── example/ example Convex app that uses this component
|
|
||||||
│ │ Run 'npx convex dev' from here during development.
|
|
||||||
│ ├── package.json.ts Thick client code goes here.
|
|
||||||
│ └── convex/
|
|
||||||
│ ├── _generated/
|
|
||||||
│ ├── convex.config.ts Imports and uses this component
|
|
||||||
│ ├── myFunctions.ts Functions that use the component
|
|
||||||
│ ├── schema.ts Example app schema
|
|
||||||
│ └── tsconfig.json
|
|
||||||
│
|
|
||||||
├── dist/ Publishing artifacts will be created here.
|
|
||||||
├── commonjs.json Used during build by TypeScript.
|
|
||||||
├── esm.json Used during build by TypeScript.
|
|
||||||
├── node10stubs.mjs Script used during build for compatibility
|
|
||||||
│ with the Metro bundler used with React Native.
|
|
||||||
├── eslint.config.mjs Recommended lints for writing a component.
|
|
||||||
│ Feel free to customize it.
|
|
||||||
└── tsconfig.json Recommended tsconfig.json for writing a component.
|
|
||||||
Some settings can be customized, some are required.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Structure of a Convex Component
|
|
||||||
|
|
||||||
A Convex components exposes the entry point convex.config.js. The on-disk
|
|
||||||
location of this file must be a directory containing implementation files. These
|
|
||||||
files should be compiled to ESM.
|
|
||||||
The package.json should contain `"type": "module"` and the tsconfig.json should
|
|
||||||
contain `"moduleResolution": "Bundler"` or `"Node16"` in order to import other
|
|
||||||
component definitions.
|
|
||||||
|
|
||||||
In addition to convex.config.js, a component typically exposes a client that
|
|
||||||
wraps communication with the component for use in the Convex
|
|
||||||
environment is typically exposed as a named export `MyComponentClient` or
|
|
||||||
`MyComponent` imported from the root package.
|
|
||||||
|
|
||||||
```
|
|
||||||
import { MyComponentClient } from "my-convex-component";
|
|
||||||
```
|
|
||||||
|
|
||||||
When frontend code is included it is typically published at a subpath:
|
|
||||||
|
|
||||||
```
|
|
||||||
import { helper } from "my-convex-component/react";
|
|
||||||
import { FrontendReactComponent } from "my-convex-component/react";
|
|
||||||
```
|
|
||||||
|
|
||||||
Frontend code should be compiled as CommonJS code as well as ESM and make use of
|
|
||||||
subpackage stubs (see next section).
|
|
||||||
|
|
||||||
If you do include frontend components, prefer peer dependencies to avoid using
|
|
||||||
more than one version of e.g. React.
|
|
||||||
|
|
||||||
### Support for Node10 module resolution
|
|
||||||
|
|
||||||
The [Metro](https://reactnative.dev/docs/metro) bundler for React Native
|
|
||||||
requires setting
|
|
||||||
[`resolver.unstable_enablePackageExports`](https://metrobundler.dev/docs/package-exports/)
|
|
||||||
in order to import code that lives in `dist/esm/react.js` from a path like
|
|
||||||
`my-convex-component/react`.
|
|
||||||
|
|
||||||
Authors of Convex component that provide frontend components are encouraged to
|
|
||||||
support these legacy "Node10-style" module resolution algorithms by generating
|
|
||||||
stub directories with special pre- and post-pack scripts.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Convex Counter Component
|
|
||||||
|
|
||||||
[](https://badge.fury.io/js/@convex-dev%2Fcounter)
|
|
||||||
|
|
||||||
**Note: Convex Components are currently in beta**
|
|
||||||
|
|
||||||
<!-- START: Include on https://convex.dev/components -->
|
<!-- START: Include on https://convex.dev/components -->
|
||||||
|
|
||||||
- [ ] What is some compelling syntax as a hook?
|
Keep your Polar subscriptions and other data synced to your Convex database.
|
||||||
- [ ] Why should you use this component?
|
|
||||||
- [ ] Links to Stack / other resources?
|
|
||||||
|
|
||||||
Found a bug? Feature request? [File it here](https://github.com/get-convex/counter/issues).
|
```ts
|
||||||
|
import { Polar } from "@convex-dev/polar";
|
||||||
|
import { components } from "./_generated/api";
|
||||||
|
|
||||||
## Pre-requisite: Convex
|
export const polar = new Polar(components.polar);
|
||||||
|
|
||||||
You'll need an existing Convex project to use the component.
|
export const listUserSubscriptions = query({
|
||||||
Convex is a hosted backend platform, including a database, serverless functions,
|
args: {
|
||||||
and a ton more you can learn about [here](https://docs.convex.dev/get-started).
|
userId: v.string(),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return polarComponent.listUserSubscriptions(ctx, args.userId);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
Run `npm create convex` or follow any of the [quickstarts](https://docs.convex.dev/home) to set one up.
|
## Prerequisites
|
||||||
|
|
||||||
|
### Polar Account
|
||||||
|
|
||||||
|
Create a Polar account and get the following credentials:
|
||||||
|
|
||||||
|
- **Access Token**
|
||||||
|
- Go to your Polar account settings and generate a new access token.
|
||||||
|
- **Organization ID**
|
||||||
|
- This is the ID of your organization in Polar, also located in settings.
|
||||||
|
- **Webhook Secret**
|
||||||
|
- Go to your Polar account settings and generate a new webhook secret.
|
||||||
|
- You'll need your webhook url, which will be your Convex deployment's HTTP
|
||||||
|
Actions URL (ends with `.convex.site`) followed by your polar event path
|
||||||
|
(default is `/events/polar`).
|
||||||
|
- You'll be able to choose which events to subscribe to. This component syncs
|
||||||
|
data from the following events if enabled in webhook settings:
|
||||||
|
- `subscription.created`
|
||||||
|
- `subscription.updated`
|
||||||
|
- `order.created`
|
||||||
|
- `benefit.created`
|
||||||
|
- `benefit.updated`
|
||||||
|
- `benefit_grant.created`
|
||||||
|
- `benefit_grant.updated`
|
||||||
|
- `product.created`
|
||||||
|
- `product.updated`
|
||||||
|
|
||||||
|
### Convex App
|
||||||
|
|
||||||
|
You'll need a Convex App to use the component. Follow any of the [Convex quickstarts](https://docs.convex.dev/home) to set one up.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Install the component package:
|
Install the component package:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
npm install @convex-dev/counter
|
npm install @convex-dev/polar
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a `convex.config.ts` file in your app's `convex/` folder and install the component by calling `use`:
|
Create a `convex.config.ts` file in your app's `convex/` folder and install the component by calling `use`:
|
||||||
@@ -154,25 +68,207 @@ Create a `convex.config.ts` file in your app's `convex/` folder and install the
|
|||||||
```ts
|
```ts
|
||||||
// convex/convex.config.ts
|
// convex/convex.config.ts
|
||||||
import { defineApp } from "convex/server";
|
import { defineApp } from "convex/server";
|
||||||
import counter from "@convex-dev/counter/convex.config";
|
import polar from "@convex-dev/polar/convex.config";
|
||||||
|
|
||||||
const app = defineApp();
|
const app = defineApp();
|
||||||
app.use(counter);
|
app.use(polar);
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
Set your API credentials:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx convex env set POLAR_ACCESS_TOKEN=xxxxx
|
||||||
|
npx convex env set POLAR_ORGANIZATION_ID=xxxxx
|
||||||
|
npx convex env set POLAR_WEBHOOK_SECRET=xxxxx
|
||||||
|
|
||||||
|
# Optional: can be sandbox or production (default: production)
|
||||||
|
npx convex env set POLAR_SERVER=sandbox
|
||||||
|
```
|
||||||
|
|
||||||
|
Instantiate a Polar Component client in a file in your app's `convex/` folder:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
// convex/example.ts
|
||||||
|
import { Polar } from "@convex-dev/polar";
|
||||||
import { components } from "./_generated/api";
|
import { components } from "./_generated/api";
|
||||||
import { Counter } from "@convex-dev/counter";
|
|
||||||
|
|
||||||
const counter = new Counter(components.counter, {
|
export const polar = new Polar(components.polar);
|
||||||
...options,
|
|
||||||
|
// Create an action to get a Polar checkout URL
|
||||||
|
export const getCheckoutUrl = action({
|
||||||
|
args: {
|
||||||
|
priceId: v.string(),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
// Call your own user query to get the current user
|
||||||
|
const user = await ctx.runQuery(api.users.getUser);
|
||||||
|
const polar = new Polar({
|
||||||
|
server: "sandbox",
|
||||||
|
accessToken: env.POLAR_ACCESS_TOKEN,
|
||||||
|
});
|
||||||
|
const result = await polar.checkouts.custom.create({
|
||||||
|
productPriceId: priceId,
|
||||||
|
successUrl: 'https://example.com/subscription-success',
|
||||||
|
customerEmail: user.email,
|
||||||
|
metadata: {
|
||||||
|
// Arbitrary metadata. This can be used to connect the user's ID with the
|
||||||
|
// Polar subscription and then associate resulting webhooks with the user
|
||||||
|
// in your system.
|
||||||
|
userId: user._id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return result.url;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// The Polar component already handles syncing data from webhooks for you, but
|
||||||
|
// you have to provide your own logic to connect a polar user id to a user in
|
||||||
|
// your system. This callback retrieves the user ID from the metadata as it was
|
||||||
|
// passed in to the checkout and then associates the polar user id with the user
|
||||||
|
// in your system.
|
||||||
|
export const polarEventCallback = internalMutation({
|
||||||
|
args: {
|
||||||
|
payload: v.any(),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
switch (args.payload.type) {
|
||||||
|
case "subscription.created": {
|
||||||
|
const payload = WebhookSubscriptionCreatedPayload$inboundSchema.parse(
|
||||||
|
args.payload,
|
||||||
|
);
|
||||||
|
// Use the metadata to connect the user's ID with the Polar subscription
|
||||||
|
const userId = payload.data.metadata.userId;
|
||||||
|
await ctx.db.patch(userId as Id<"users">, {
|
||||||
|
polarId: payload.data.userId,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Register Polar webhook handlers by creating an `http.ts` file in your `convex/` folder and use the client you've exported above:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// http.ts
|
||||||
|
import { polar } from "./example";
|
||||||
|
import { httpRouter } from "convex/server";
|
||||||
|
import { internal } from "./_generated/api";
|
||||||
|
|
||||||
|
const http = httpRouter();
|
||||||
|
|
||||||
|
// this call registers the routes necessary for the component
|
||||||
|
polar.registerRoutes(http, {
|
||||||
|
// Optionally override the default path that Polar events will be sent to
|
||||||
|
// (default is /events/polar)
|
||||||
|
path: "/events/polar",
|
||||||
|
// Optionally provide a callback to run on each event
|
||||||
|
eventCallback: internal.example.polarEventCallback,
|
||||||
|
});
|
||||||
|
export default http;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Querying Polar data
|
||||||
|
|
||||||
|
To list all subscriptions for a user, use the `listUserSubscriptions` method in your Convex function.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// convex/subscriptions.ts
|
||||||
|
export const listUserSubscriptions = query({
|
||||||
|
args: {
|
||||||
|
// Note: this is the user's Polar ID, not their ID from your system. See
|
||||||
|
// above for how to retrieve and store the user's Polar ID with your system
|
||||||
|
// user data.
|
||||||
|
userId: v.string(),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.listUserSubscriptions, {
|
||||||
|
userId: args.userId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
List user benefit grants:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export const listUserBenefitGrants = query({
|
||||||
|
args: {
|
||||||
|
userId: v.string(),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.listUserBenefitGrants, {
|
||||||
|
userId: args.userId,
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
See more example usage in [example.ts](./example/convex/example.ts).
|
To list all products, use `listProducts`:
|
||||||
|
|
||||||
<!-- END: Include on https://convex.dev/components -->
|
```ts
|
||||||
|
export const listProducts = query({
|
||||||
|
args: {},
|
||||||
|
handler: async (ctx) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.listProducts, {
|
||||||
|
includeArchived: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Get data by ID:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export const getSubscription = query({
|
||||||
|
args: {
|
||||||
|
id: v.id("subscriptions"),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.getSubscription, { id: args.id });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getOrder = query({
|
||||||
|
args: {
|
||||||
|
id: v.id("orders"),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.getOrder, { id: args.id });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getProduct = query({
|
||||||
|
args: {
|
||||||
|
id: v.id("products"),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.getProduct, { id: args.id });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getBenefit = query({
|
||||||
|
args: {
|
||||||
|
id: v.id("benefits"),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.getBenefit, { id: args.id });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getBenefitGrant = query({
|
||||||
|
args: {
|
||||||
|
id: v.id("benefitGrants"),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
return ctx.runQuery(polar.component.lib.getBenefitGrant, { id: args.id });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- END: Include on https://convex.dev/components -->
|
||||||
@@ -1,90 +1,3 @@
|
|||||||
# Welcome to your Convex functions directory!
|
# Example app
|
||||||
|
|
||||||
Write your Convex functions here.
|
This app uses the Polar component.
|
||||||
See https://docs.convex.dev/functions for more.
|
|
||||||
|
|
||||||
A query function that takes two arguments looks like:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// functions.js
|
|
||||||
import { query } from "./_generated/server";
|
|
||||||
import { v } from "convex/values";
|
|
||||||
|
|
||||||
export const myQueryFunction = query({
|
|
||||||
// Validators for arguments.
|
|
||||||
args: {
|
|
||||||
first: v.number(),
|
|
||||||
second: v.string(),
|
|
||||||
},
|
|
||||||
|
|
||||||
// Function implementation.
|
|
||||||
handler: async (ctx, args) => {
|
|
||||||
// Read the database as many times as you need here.
|
|
||||||
// See https://docs.convex.dev/database/reading-data.
|
|
||||||
const documents = await ctx.db.query("tablename").collect();
|
|
||||||
|
|
||||||
// Arguments passed from the client are properties of the args object.
|
|
||||||
console.log(args.first, args.second);
|
|
||||||
|
|
||||||
// Write arbitrary JavaScript here: filter, aggregate, build derived data,
|
|
||||||
// remove non-public properties, or create new objects.
|
|
||||||
return documents;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Using this query function in a React component looks like:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const data = useQuery(api.functions.myQueryFunction, {
|
|
||||||
first: 10,
|
|
||||||
second: "hello",
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
A mutation function looks like:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// functions.js
|
|
||||||
import { mutation } from "./_generated/server";
|
|
||||||
import { v } from "convex/values";
|
|
||||||
|
|
||||||
export const myMutationFunction = mutation({
|
|
||||||
// Validators for arguments.
|
|
||||||
args: {
|
|
||||||
first: v.string(),
|
|
||||||
second: v.string(),
|
|
||||||
},
|
|
||||||
|
|
||||||
// Function implementation.
|
|
||||||
handler: async (ctx, args) => {
|
|
||||||
// Insert or modify documents in the database here.
|
|
||||||
// Mutations can also read from the database like queries.
|
|
||||||
// See https://docs.convex.dev/database/writing-data.
|
|
||||||
const message = { body: args.first, author: args.second };
|
|
||||||
const id = await ctx.db.insert("messages", message);
|
|
||||||
|
|
||||||
// Optionally, return a value from your mutation.
|
|
||||||
return await ctx.db.get(id);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Using this mutation function in a React component looks like:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const mutation = useMutation(api.functions.myMutationFunction);
|
|
||||||
function handleButtonPress() {
|
|
||||||
// fire and forget, the most common way to use mutations
|
|
||||||
mutation({ first: "Hello!", second: "me" });
|
|
||||||
// OR
|
|
||||||
// use the result once the mutation has completed
|
|
||||||
mutation({ first: "Hello!", second: "me" }).then((result) =>
|
|
||||||
console.log(result),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the Convex CLI to push your functions to a deployment. See everything
|
|
||||||
the Convex CLI can do by running `npx convex -h` in your project root
|
|
||||||
directory. To learn more, launch the docs with `npx convex docs`.
|
|
||||||
@@ -5,23 +5,25 @@ import { query, internalMutation } from "./_generated/server";
|
|||||||
import { components } from "./_generated/api";
|
import { components } from "./_generated/api";
|
||||||
import { Id } from "./_generated/dataModel";
|
import { Id } from "./_generated/dataModel";
|
||||||
|
|
||||||
const polarComponent = new Polar(components.polar);
|
const polar = new Polar(components.polar);
|
||||||
|
|
||||||
export const listProducts = query({
|
export const listProducts = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
return polarComponent.listProducts(ctx, {
|
return ctx.runQuery(polar.component.lib.listProducts, {
|
||||||
includeArchived: false,
|
includeArchived: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getUserSubscriptions = query({
|
export const listUserSubscriptions = query({
|
||||||
args: {
|
args: {
|
||||||
userId: v.string(),
|
userId: v.string(),
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
return polarComponent.listUserSubscriptions(ctx, args.userId);
|
return ctx.runQuery(polar.component.lib.listUserSubscriptions, {
|
||||||
|
userId: args.userId,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Polar as PolarComponent } from "@convex-dev/polar";
|
import { Polar } from "@convex-dev/polar";
|
||||||
import { httpRouter } from "convex/server";
|
import { httpRouter } from "convex/server";
|
||||||
import { components, internal } from "./_generated/api";
|
import { components, internal } from "./_generated/api";
|
||||||
|
|
||||||
const http = httpRouter();
|
const http = httpRouter();
|
||||||
|
|
||||||
const polarComponent = new PolarComponent(components.polar);
|
const polar = new Polar(components.polar);
|
||||||
|
|
||||||
polarComponent.registerRoutes(http, {
|
polar.registerRoutes(http, {
|
||||||
path: "/events/polar",
|
path: "/events/polar",
|
||||||
eventCallback: internal.example.polarEventCallback,
|
eventCallback: internal.example.polarEventCallback,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,19 +56,6 @@ export type EventHandler = FunctionReference<
|
|||||||
export class Polar {
|
export class Polar {
|
||||||
constructor(public component: ComponentApi) {}
|
constructor(public component: ComponentApi) {}
|
||||||
|
|
||||||
async listUserSubscriptions(ctx: RunQueryCtx, userId: string) {
|
|
||||||
return ctx.runQuery(this.component.lib.listUserSubscriptions, {
|
|
||||||
userId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async listProducts(
|
|
||||||
ctx: RunQueryCtx,
|
|
||||||
{ includeArchived = false }: { includeArchived?: boolean } = {}
|
|
||||||
) {
|
|
||||||
return ctx.runQuery(this.component.lib.listProducts, { includeArchived });
|
|
||||||
}
|
|
||||||
|
|
||||||
registerRoutes(
|
registerRoutes(
|
||||||
http: HttpRouter,
|
http: HttpRouter,
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user