diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index 6e7d8de5..606a5476 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -1,6 +1,6 @@
# This workflow is triggered when a GitHub release is created.
# It can also be run manually to re-publish to NPM in case it failed for some reason.
-# You can run this workflow by navigating to https://www.github.com/flowglad/flowglad-ts/actions/workflows/publish-npm.yml
+# You can run this workflow by navigating to https://www.github.com/flowglad/flowglad-node/actions/workflows/publish-npm.yml
name: Publish NPM
on:
workflow_dispatch:
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 6ef3063f..9bd703fd 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -9,7 +9,7 @@ jobs:
release_doctor:
name: release doctor
runs-on: ubuntu-latest
- if: github.repository == 'flowglad/flowglad-ts' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
+ if: github.repository == 'flowglad/flowglad-node' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
steps:
- uses: actions/checkout@v4
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 67dcd73f..d7a87356 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.0.1-alpha.0"
+ ".": "0.1.0-alpha.1"
}
diff --git a/.stats.yml b/.stats.yml
index 33a2526e..7a0c1c75 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 1
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad%2Fflowglad-21870271879fc260da63af686a116fc7e99c28c684ca92c127d6d9cbbd456c46.yml
+configured_endpoints: 11
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad%2Fflowglad-cbe092963a0dbbc2eddd8cd406d288a766607a771441afb939424b13e2895151.yml
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..21eb1c20
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,27 @@
+# Changelog
+
+## 0.1.0-alpha.1 (2025-01-24)
+
+Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/flowglad/flowglad-node/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
+
+### Features
+
+* **api:** clean up ambiguous types, rm installment amounts ([#7](https://github.com/flowglad/flowglad-node/issues/7)) ([4d683db](https://github.com/flowglad/flowglad-node/commit/4d683db6df39ea87f265a1c2b75cce56d50dc674))
+<<<<<<< HEAD
+=======
+* **api:** Config update for agreea/dev ([#8](https://github.com/flowglad/flowglad-node/issues/8)) ([5e67321](https://github.com/flowglad/flowglad-node/commit/5e6732112006af37941429877446b3435d8d3dce))
+>>>>>>> f1544f8fc9d31b06bc5756f15107c060ce2cfa11
+* **api:** Fix flowglad API key ([#5](https://github.com/flowglad/flowglad-node/issues/5)) ([8664078](https://github.com/flowglad/flowglad-node/commit/8664078e6a187fd41107c92ad218d6e4ea0c618d))
+* **api:** update environments ([#4](https://github.com/flowglad/flowglad-node/issues/4)) ([89660fa](https://github.com/flowglad/flowglad-node/commit/89660fa46a132f14db52872c02c8af1bd6db4d41))
+* **api:** update README ([#3](https://github.com/flowglad/flowglad-node/issues/3)) ([f85399a](https://github.com/flowglad/flowglad-node/commit/f85399ac9f8fcc029b94a4e5d4bef93fd9c142f8))
+* **api:** update via SDK Studio ([ad440b3](https://github.com/flowglad/flowglad-node/commit/ad440b3c874102554e9b49c46e50a527adf3d39d))
+* **api:** update via SDK Studio ([eed05a8](https://github.com/flowglad/flowglad-node/commit/eed05a8f65579e7ec6fe6057531c4eb05c6d4633))
+* **api:** update via SDK Studio ([25bf945](https://github.com/flowglad/flowglad-node/commit/25bf9459857098b79f15d735cfd7b4684793f2db))
+* **api:** update via SDK Studio ([5101375](https://github.com/flowglad/flowglad-node/commit/51013751991b0104e25992e58e7b7c5acc6e9e11))
+
+
+### Chores
+
+* go live ([#1](https://github.com/flowglad/flowglad-node/issues/1)) ([b235c12](https://github.com/flowglad/flowglad-node/commit/b235c12823b0ae452a85a45094f42fe6f527fc9e))
+* go live ([#2](https://github.com/flowglad/flowglad-node/issues/2)) ([0724d46](https://github.com/flowglad/flowglad-node/commit/0724d469b1711f6ff2e26d0d7073cd2d1d9d1e81))
+* **internal:** add test ([#6](https://github.com/flowglad/flowglad-node/issues/6)) ([b479989](https://github.com/flowglad/flowglad-node/commit/b479989a2de24caeee2d590d9304fcf6c53a59aa))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 59305316..a9056f24 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -42,15 +42,15 @@ If you’d like to use the repository from source, you can either install from g
To install via git:
```sh
-$ npm install git+ssh://git@github.com:flowglad/flowglad-ts.git
+$ npm install git+ssh://git@github.com:flowglad/flowglad-node.git
```
Alternatively, to link a local copy of the repo:
```sh
# Clone
-$ git clone https://www.github.com/flowglad/flowglad-ts
-$ cd flowglad-ts
+$ git clone https://www.github.com/flowglad/flowglad-node
+$ cd flowglad-node
# With yarn
$ yarn link
@@ -99,7 +99,7 @@ the changes aren't made through the automated pipeline, you may want to make rel
### Publish with a GitHub workflow
-You can release to package managers by using [the `Publish NPM` GitHub action](https://www.github.com/flowglad/flowglad-ts/actions/workflows/publish-npm.yml). This requires a setup organization or repository secret to be set up.
+You can release to package managers by using [the `Publish NPM` GitHub action](https://www.github.com/flowglad/flowglad-node/actions/workflows/publish-npm.yml). This requires a setup organization or repository secret to be set up.
### Publish manually
diff --git a/README.md b/README.md
index 432ad859..98d39938 100644
--- a/README.md
+++ b/README.md
@@ -22,22 +22,13 @@ The full API of this library can be found in [api.md](api.md).
```js
import Flowglad from '@flowglad/node';
-const client = new Flowglad();
+const client = new Flowglad({
+ environment: 'staging', // defaults to 'production'
+});
async function main() {
const customerProfile = await client.customerProfiles.create({
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
+ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' },
});
console.log(customerProfile.data);
@@ -54,22 +45,13 @@ This library includes TypeScript definitions for all request params and response
```ts
import Flowglad from '@flowglad/node';
-const client = new Flowglad();
+const client = new Flowglad({
+ environment: 'staging', // defaults to 'production'
+});
async function main() {
const params: Flowglad.CustomerProfileCreateParams = {
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
+ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' },
};
const customerProfile: Flowglad.CustomerProfileCreateResponse = await client.customerProfiles.create(
params,
@@ -91,20 +73,7 @@ a subclass of `APIError` will be thrown:
```ts
async function main() {
const customerProfile = await client.customerProfiles
- .create({
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
- })
+ .create({ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } })
.catch(async (err) => {
if (err instanceof Flowglad.APIError) {
console.log(err.status); // 400
@@ -148,7 +117,7 @@ const client = new Flowglad({
});
// Or, configure per-request:
-await client.customerProfiles.create({ customerProfile: { '0': 'R', '1': 'E', '2': 'P', '3': 'L', '4': 'A', '5': 'C', '6': 'E', '7': '_', '8': 'M', '9': 'E' } }, {
+await client.customerProfiles.create({ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } }, {
maxRetries: 5,
});
```
@@ -165,7 +134,7 @@ const client = new Flowglad({
});
// Override per-request:
-await client.customerProfiles.create({ customerProfile: { '0': 'R', '1': 'E', '2': 'P', '3': 'L', '4': 'A', '5': 'C', '6': 'E', '7': '_', '8': 'M', '9': 'E' } }, {
+await client.customerProfiles.create({ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } }, {
timeout: 5 * 1000,
});
```
@@ -187,39 +156,13 @@ You can also use the `.withResponse()` method to get the raw `Response` along wi
const client = new Flowglad();
const response = await client.customerProfiles
- .create({
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
- })
+ .create({ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } })
.asResponse();
console.log(response.headers.get('X-My-Header'));
console.log(response.statusText); // access the underlying Response object
const { data: customerProfile, response: raw } = await client.customerProfiles
- .create({
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
- })
+ .create({ customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } })
.withResponse();
console.log(raw.headers.get('X-My-Header'));
console.log(customerProfile.data);
@@ -285,7 +228,7 @@ import Flowglad from '@flowglad/node';
```
To do the inverse, add `import "@flowglad/node/shims/node"` (which does import polyfills).
-This can also be useful if you are getting the wrong TypeScript types for `Response` ([more details](https://github.com/flowglad/flowglad-ts/tree/main/src/_shims#readme)).
+This can also be useful if you are getting the wrong TypeScript types for `Response` ([more details](https://github.com/flowglad/flowglad-node/tree/main/src/_shims#readme)).
### Logging and middleware
@@ -327,20 +270,7 @@ const client = new Flowglad({
// Override per-request:
await client.customerProfiles.create(
- {
- customerProfile: {
- '0': 'R',
- '1': 'E',
- '2': 'P',
- '3': 'L',
- '4': 'A',
- '5': 'C',
- '6': 'E',
- '7': '_',
- '8': 'M',
- '9': 'E',
- },
- },
+ { customerProfile: { externalId: 'myId', email: 'scrooge@mcduck.me', name: 'Scrooge McDuck' } },
{
httpAgent: new http.Agent({ keepAlive: false }),
},
@@ -357,7 +287,7 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
-We are keen for your feedback; please open an [issue](https://www.github.com/flowglad/flowglad-ts/issues) with questions, bugs, or suggestions.
+We are keen for your feedback; please open an [issue](https://www.github.com/flowglad/flowglad-node/issues) with questions, bugs, or suggestions.
## Requirements
diff --git a/api.md b/api.md
index 4a997625..c9adfe43 100644
--- a/api.md
+++ b/api.md
@@ -1,9 +1,61 @@
+# PurchaseSessions
+
+Types:
+
+- PurchaseSessionCreateResponse
+
+Methods:
+
+- client.purchaseSessions.create({ ...params }) -> PurchaseSessionCreateResponse
+
+# Products
+
+Types:
+
+- ProductCreateResponse
+- ProductUpdateResponse
+- ProductListResponse
+
+Methods:
+
+- client.products.create({ ...params }) -> ProductCreateResponse
+- client.products.update(id, { ...params }) -> ProductUpdateResponse
+- client.products.list({ ...params }) -> ProductListResponse
+
+# Variants
+
+Types:
+
+- VariantCreateResponse
+- VariantUpdateResponse
+- VariantListResponse
+
+Methods:
+
+- client.variants.create({ ...params }) -> VariantCreateResponse
+- client.variants.update(id, { ...params }) -> VariantUpdateResponse
+- client.variants.list({ ...params }) -> VariantListResponse
+
# CustomerProfiles
Types:
-- CustomerProfileCreateResponse
+- CustomerProfileCreateResponse
+- CustomerProfileRetrieveResponse
+- CustomerProfileUpdateResponse
+
+Methods:
+
+- client.customerProfiles.create({ ...params }) -> CustomerProfileCreateResponse
+- client.customerProfiles.retrieve(externalId) -> CustomerProfileRetrieveResponse
+- client.customerProfiles.update(externalId, { ...params }) -> CustomerProfileUpdateResponse
+
+## Billing
+
+Types:
+
+- BillingRetrieveResponse
Methods:
-- client.customerProfiles.create({ ...params }) -> CustomerProfileCreateResponse
+- client.customerProfiles.billing.retrieve(externalId) -> BillingRetrieveResponse
diff --git a/package.json b/package.json
index 081938a2..5d88bf34 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
"name": "@flowglad/node",
- "version": "0.0.1-alpha.0",
+ "version": "0.1.0-alpha.1",
"description": "The official TypeScript library for the Flowglad API",
"author": "Flowglad ",
"types": "dist/index.d.ts",
"main": "dist/index.js",
"type": "commonjs",
- "repository": "github:flowglad/flowglad-ts",
+ "repository": "github:flowglad/flowglad-node",
"license": "Apache-2.0",
"packageManager": "yarn@1.22.22",
"files": [
diff --git a/src/_shims/index-deno.ts b/src/_shims/index-deno.ts
index b3135a17..b48b503b 100644
--- a/src/_shims/index-deno.ts
+++ b/src/_shims/index-deno.ts
@@ -79,7 +79,7 @@ export function getDefaultAgent(url: string) {
}
export function fileFromPath() {
throw new Error(
- 'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/flowglad/flowglad-ts#file-uploads',
+ 'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/flowglad/flowglad-node#file-uploads',
);
}
diff --git a/src/_shims/web-runtime.ts b/src/_shims/web-runtime.ts
index 1e1b830d..f69e98d7 100644
--- a/src/_shims/web-runtime.ts
+++ b/src/_shims/web-runtime.ts
@@ -95,7 +95,7 @@ export function getRuntime({ manuallyImported }: { manuallyImported?: boolean }
getDefaultAgent: (url: string) => undefined,
fileFromPath: () => {
throw new Error(
- 'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/flowglad/flowglad-ts#file-uploads',
+ 'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/flowglad/flowglad-node#file-uploads',
);
},
isFsReadStream: (value: any) => false,
diff --git a/src/index.ts b/src/index.ts
index 0d34c307..3988c67a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,18 +5,59 @@ import * as Core from './core';
import * as Errors from './error';
import * as Uploads from './uploads';
import * as API from './resources/index';
+import {
+ ProductCreateParams,
+ ProductCreateResponse,
+ ProductListParams,
+ ProductListResponse,
+ ProductUpdateParams,
+ ProductUpdateResponse,
+ Products,
+} from './resources/products';
+import {
+ PurchaseSessionCreateParams,
+ PurchaseSessionCreateResponse,
+ PurchaseSessions,
+} from './resources/purchase-sessions';
+import {
+ VariantCreateParams,
+ VariantCreateResponse,
+ VariantListParams,
+ VariantListResponse,
+ VariantUpdateParams,
+ VariantUpdateResponse,
+ Variants,
+} from './resources/variants';
import {
CustomerProfileCreateParams,
CustomerProfileCreateResponse,
+ CustomerProfileRetrieveResponse,
+ CustomerProfileUpdateParams,
+ CustomerProfileUpdateResponse,
CustomerProfiles,
-} from './resources/customer-profiles';
+} from './resources/customer-profiles/customer-profiles';
+
+const environments = {
+ production: 'https://app.flowglad.com/api/v1',
+ staging: 'https://staging.flowglad.com/api/v1',
+};
+type Environment = keyof typeof environments;
export interface ClientOptions {
/**
- * API key for accessing the Flowglad API
+ * API key to be set in the Authorization header
*/
apiKey?: string | undefined;
+ /**
+ * Specifies the environment to use for the API.
+ *
+ * Each environment maps to a different base URL:
+ * - `production` corresponds to `https://app.flowglad.com/api/v1`
+ * - `staging` corresponds to `https://staging.flowglad.com/api/v1`
+ */
+ environment?: Environment | undefined;
+
/**
* Override the default base URL for the API, e.g., "https://api.example.com/v2/"
*
@@ -85,8 +126,9 @@ export class Flowglad extends Core.APIClient {
/**
* API Client for interfacing with the Flowglad API.
*
- * @param {string | undefined} [opts.apiKey=process.env['FLOWGLAD_API_KEY'] ?? undefined]
- * @param {string} [opts.baseURL=process.env['FLOWGLAD_BASE_URL'] ?? http://localhost:3000/] - Override the default base URL for the API.
+ * @param {string | undefined} [opts.apiKey=process.env['FLOWGLAD_SECRET_KEY'] ?? undefined]
+ * @param {Environment} [opts.environment=production] - Specifies the environment URL to use for the API.
+ * @param {string} [opts.baseURL=process.env['FLOWGLAD_BASE_URL'] ?? https://app.flowglad.com/api/v1] - Override the default base URL for the API.
* @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
* @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
* @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
@@ -96,23 +138,30 @@ export class Flowglad extends Core.APIClient {
*/
constructor({
baseURL = Core.readEnv('FLOWGLAD_BASE_URL'),
- apiKey = Core.readEnv('FLOWGLAD_API_KEY'),
+ apiKey = Core.readEnv('FLOWGLAD_SECRET_KEY'),
...opts
}: ClientOptions = {}) {
if (apiKey === undefined) {
throw new Errors.FlowgladError(
- "The FLOWGLAD_API_KEY environment variable is missing or empty; either provide it, or instantiate the Flowglad client with an apiKey option, like new Flowglad({ apiKey: 'My API Key' }).",
+ "The FLOWGLAD_SECRET_KEY environment variable is missing or empty; either provide it, or instantiate the Flowglad client with an apiKey option, like new Flowglad({ apiKey: 'My API Key' }).",
);
}
const options: ClientOptions = {
apiKey,
...opts,
- baseURL: baseURL || `http://localhost:3000/`,
+ baseURL,
+ environment: opts.environment ?? 'production',
};
+ if (baseURL && opts.environment) {
+ throw new Errors.FlowgladError(
+ 'Ambiguous URL; The `baseURL` option (or FLOWGLAD_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null',
+ );
+ }
+
super({
- baseURL: options.baseURL!,
+ baseURL: options.baseURL || environments[options.environment || 'production'],
timeout: options.timeout ?? 60000 /* 1 minute */,
httpAgent: options.httpAgent,
maxRetries: options.maxRetries,
@@ -124,6 +173,9 @@ export class Flowglad extends Core.APIClient {
this.apiKey = apiKey;
}
+ purchaseSessions: API.PurchaseSessions = new API.PurchaseSessions(this);
+ products: API.Products = new API.Products(this);
+ variants: API.Variants = new API.Variants(this);
customerProfiles: API.CustomerProfiles = new API.CustomerProfiles(this);
protected override defaultQuery(): Core.DefaultQuery | undefined {
@@ -162,14 +214,46 @@ export class Flowglad extends Core.APIClient {
static fileFromPath = Uploads.fileFromPath;
}
+Flowglad.PurchaseSessions = PurchaseSessions;
+Flowglad.Products = Products;
+Flowglad.Variants = Variants;
Flowglad.CustomerProfiles = CustomerProfiles;
export declare namespace Flowglad {
export type RequestOptions = Core.RequestOptions;
+ export {
+ PurchaseSessions as PurchaseSessions,
+ type PurchaseSessionCreateResponse as PurchaseSessionCreateResponse,
+ type PurchaseSessionCreateParams as PurchaseSessionCreateParams,
+ };
+
+ export {
+ Products as Products,
+ type ProductCreateResponse as ProductCreateResponse,
+ type ProductUpdateResponse as ProductUpdateResponse,
+ type ProductListResponse as ProductListResponse,
+ type ProductCreateParams as ProductCreateParams,
+ type ProductUpdateParams as ProductUpdateParams,
+ type ProductListParams as ProductListParams,
+ };
+
+ export {
+ Variants as Variants,
+ type VariantCreateResponse as VariantCreateResponse,
+ type VariantUpdateResponse as VariantUpdateResponse,
+ type VariantListResponse as VariantListResponse,
+ type VariantCreateParams as VariantCreateParams,
+ type VariantUpdateParams as VariantUpdateParams,
+ type VariantListParams as VariantListParams,
+ };
+
export {
CustomerProfiles as CustomerProfiles,
type CustomerProfileCreateResponse as CustomerProfileCreateResponse,
+ type CustomerProfileRetrieveResponse as CustomerProfileRetrieveResponse,
+ type CustomerProfileUpdateResponse as CustomerProfileUpdateResponse,
type CustomerProfileCreateParams as CustomerProfileCreateParams,
+ type CustomerProfileUpdateParams as CustomerProfileUpdateParams,
};
}
diff --git a/src/resources/customer-profiles.ts b/src/resources/customer-profiles.ts
deleted file mode 100644
index b1545067..00000000
--- a/src/resources/customer-profiles.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '../resource';
-import * as Core from '../core';
-
-export class CustomerProfiles extends APIResource {
- /**
- * Create a customer profile
- */
- create(
- body: CustomerProfileCreateParams,
- options?: Core.RequestOptions,
- ): Core.APIPromise {
- return this._client.post('/api/v1/customer-profiles', { body, ...options });
- }
-}
-
-export interface CustomerProfileCreateResponse {
- data: CustomerProfileCreateResponse.Data;
-}
-
-export namespace CustomerProfileCreateResponse {
- export interface Data {
- customerProfile: Data.CustomerProfile;
- }
-
- export namespace Data {
- export interface CustomerProfile {
- id: string;
-
- archived: boolean;
-
- billingAddress: CustomerProfile.BillingAddress | null;
-
- createdAt: string;
-
- CustomerId: string;
-
- domain: string | null;
-
- email: string;
-
- iconURL: string | null;
-
- invoiceNumberBase: string | null;
-
- livemode: boolean;
-
- logoURL: string | null;
-
- name: string | null;
-
- OrganizationId: string;
-
- updatedAt: string | null;
- }
-
- export namespace CustomerProfile {
- export interface BillingAddress {
- address: BillingAddress.Address;
-
- name: string;
-
- firstName?: string;
-
- lastName?: string;
-
- phone?: string;
- }
-
- export namespace BillingAddress {
- export interface Address {
- city: string;
-
- country: string;
-
- line1: string;
-
- line2: string | null;
-
- postal_code: string;
-
- state: string;
- }
- }
- }
- }
-}
-
-export interface CustomerProfileCreateParams {
- customerProfile: CustomerProfileCreateParams.CustomerProfile;
-}
-
-export namespace CustomerProfileCreateParams {
- export interface CustomerProfile {
- CustomerId: string;
-
- email: string;
-
- OrganizationId: string;
-
- archived?: boolean;
-
- customerTaxId?: string | null;
-
- domain?: string | null;
-
- iconURL?: string | null;
-
- invoiceNumberBase?: string | null;
-
- livemode?: boolean;
-
- logoURL?: string | null;
-
- name?: string | null;
-
- slackId?: string | null;
-
- stripeCustomerId?: string | null;
- }
-}
-
-export declare namespace CustomerProfiles {
- export {
- type CustomerProfileCreateResponse as CustomerProfileCreateResponse,
- type CustomerProfileCreateParams as CustomerProfileCreateParams,
- };
-}
diff --git a/src/resources/customer-profiles/billing.ts b/src/resources/customer-profiles/billing.ts
new file mode 100644
index 00000000..fe0fa0da
--- /dev/null
+++ b/src/resources/customer-profiles/billing.ts
@@ -0,0 +1,85 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../resource';
+import * as Core from '../../core';
+
+export class Billing extends APIResource {
+ /**
+ * Gets all the billing details for a customer
+ */
+ retrieve(externalId: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.get(`/api/v1/customer-profiles/${externalId}/billing`, options);
+ }
+}
+
+export interface BillingRetrieveResponse {
+ customerProfile: BillingRetrieveResponse.CustomerProfile;
+}
+
+export namespace BillingRetrieveResponse {
+ export interface CustomerProfile {
+ id: string;
+
+ archived: boolean;
+
+ billingAddress: CustomerProfile.BillingAddress | null;
+
+ createdAt: string;
+
+ CustomerId: string;
+
+ domain: string | null;
+
+ email: string;
+
+ externalId: string;
+
+ iconURL: string | null;
+
+ invoiceNumberBase: string | null;
+
+ livemode: boolean;
+
+ logoURL: string | null;
+
+ name: string | null;
+
+ OrganizationId: string;
+
+ updatedAt: string | null;
+ }
+
+ export namespace CustomerProfile {
+ export interface BillingAddress {
+ address: BillingAddress.Address;
+
+ name: string;
+
+ firstName?: string;
+
+ lastName?: string;
+
+ phone?: string;
+ }
+
+ export namespace BillingAddress {
+ export interface Address {
+ city: string;
+
+ country: string;
+
+ line1: string;
+
+ line2: string | null;
+
+ postal_code: string;
+
+ state: string;
+ }
+ }
+ }
+}
+
+export declare namespace Billing {
+ export { type BillingRetrieveResponse as BillingRetrieveResponse };
+}
diff --git a/src/resources/customer-profiles/customer-profiles.ts b/src/resources/customer-profiles/customer-profiles.ts
new file mode 100644
index 00000000..3d8882d1
--- /dev/null
+++ b/src/resources/customer-profiles/customer-profiles.ts
@@ -0,0 +1,311 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../resource';
+import * as Core from '../../core';
+import * as BillingAPI from './billing';
+import { Billing, BillingRetrieveResponse } from './billing';
+
+export class CustomerProfiles extends APIResource {
+ billing: BillingAPI.Billing = new BillingAPI.Billing(this._client);
+
+ /**
+ * Create customerProfiles
+ */
+ create(
+ body: CustomerProfileCreateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.post('/api/v1/customer-profiles', { body, ...options });
+ }
+
+ /**
+ * Get customerProfiles
+ */
+ retrieve(
+ externalId: string,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.get(`/api/v1/customer-profiles/${externalId}`, options);
+ }
+
+ /**
+ * Update customerProfiles
+ */
+ update(
+ externalId: string,
+ body: CustomerProfileUpdateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.put(`/api/v1/customer-profiles/${externalId}`, { body, ...options });
+ }
+}
+
+export interface CustomerProfileCreateResponse {
+ data: CustomerProfileCreateResponse.Data;
+}
+
+export namespace CustomerProfileCreateResponse {
+ export interface Data {
+ customerProfile: Data.CustomerProfile;
+ }
+
+ export namespace Data {
+ export interface CustomerProfile {
+ id: string;
+
+ archived: boolean;
+
+ billingAddress: CustomerProfile.BillingAddress | null;
+
+ createdAt: string;
+
+ CustomerId: string;
+
+ domain: string | null;
+
+ email: string;
+
+ externalId: string;
+
+ iconURL: string | null;
+
+ invoiceNumberBase: string | null;
+
+ livemode: boolean;
+
+ logoURL: string | null;
+
+ name: string | null;
+
+ OrganizationId: string;
+
+ updatedAt: string | null;
+ }
+
+ export namespace CustomerProfile {
+ export interface BillingAddress {
+ address: BillingAddress.Address;
+
+ name: string;
+
+ firstName?: string;
+
+ lastName?: string;
+
+ phone?: string;
+ }
+
+ export namespace BillingAddress {
+ export interface Address {
+ city: string;
+
+ country: string;
+
+ line1: string;
+
+ line2: string | null;
+
+ postal_code: string;
+
+ state: string;
+ }
+ }
+ }
+ }
+}
+
+export interface CustomerProfileRetrieveResponse {
+ customerProfile: CustomerProfileRetrieveResponse.CustomerProfile;
+}
+
+export namespace CustomerProfileRetrieveResponse {
+ export interface CustomerProfile {
+ id: string;
+
+ archived: boolean;
+
+ billingAddress: CustomerProfile.BillingAddress | null;
+
+ createdAt: string;
+
+ CustomerId: string;
+
+ domain: string | null;
+
+ email: string;
+
+ externalId: string;
+
+ iconURL: string | null;
+
+ invoiceNumberBase: string | null;
+
+ livemode: boolean;
+
+ logoURL: string | null;
+
+ name: string | null;
+
+ OrganizationId: string;
+
+ updatedAt: string | null;
+ }
+
+ export namespace CustomerProfile {
+ export interface BillingAddress {
+ address: BillingAddress.Address;
+
+ name: string;
+
+ firstName?: string;
+
+ lastName?: string;
+
+ phone?: string;
+ }
+
+ export namespace BillingAddress {
+ export interface Address {
+ city: string;
+
+ country: string;
+
+ line1: string;
+
+ line2: string | null;
+
+ postal_code: string;
+
+ state: string;
+ }
+ }
+ }
+}
+
+export interface CustomerProfileUpdateResponse {
+ customerProfile: CustomerProfileUpdateResponse.CustomerProfile;
+}
+
+export namespace CustomerProfileUpdateResponse {
+ export interface CustomerProfile {
+ id: string;
+
+ archived: boolean;
+
+ billingAddress: CustomerProfile.BillingAddress | null;
+
+ createdAt: string;
+
+ CustomerId: string;
+
+ domain: string | null;
+
+ email: string;
+
+ externalId: string;
+
+ iconURL: string | null;
+
+ invoiceNumberBase: string | null;
+
+ livemode: boolean;
+
+ logoURL: string | null;
+
+ name: string | null;
+
+ OrganizationId: string;
+
+ updatedAt: string | null;
+ }
+
+ export namespace CustomerProfile {
+ export interface BillingAddress {
+ address: BillingAddress.Address;
+
+ name: string;
+
+ firstName?: string;
+
+ lastName?: string;
+
+ phone?: string;
+ }
+
+ export namespace BillingAddress {
+ export interface Address {
+ city: string;
+
+ country: string;
+
+ line1: string;
+
+ line2: string | null;
+
+ postal_code: string;
+
+ state: string;
+ }
+ }
+ }
+}
+
+export interface CustomerProfileCreateParams {
+ customerProfile: CustomerProfileCreateParams.CustomerProfile;
+}
+
+export namespace CustomerProfileCreateParams {
+ export interface CustomerProfile {
+ email: string;
+
+ externalId: string;
+
+ archived?: boolean;
+
+ domain?: string | null;
+
+ iconURL?: string | null;
+
+ logoURL?: string | null;
+
+ name?: string | null;
+ }
+}
+
+export interface CustomerProfileUpdateParams {
+ customerProfile: CustomerProfileUpdateParams.CustomerProfile;
+}
+
+export namespace CustomerProfileUpdateParams {
+ export interface CustomerProfile {
+ id: string;
+
+ archived?: boolean;
+
+ domain?: string | null;
+
+ email?: string;
+
+ externalId?: string;
+
+ iconURL?: string | null;
+
+ logoURL?: string | null;
+
+ name?: string | null;
+ }
+}
+
+CustomerProfiles.Billing = Billing;
+
+export declare namespace CustomerProfiles {
+ export {
+ type CustomerProfileCreateResponse as CustomerProfileCreateResponse,
+ type CustomerProfileRetrieveResponse as CustomerProfileRetrieveResponse,
+ type CustomerProfileUpdateResponse as CustomerProfileUpdateResponse,
+ type CustomerProfileCreateParams as CustomerProfileCreateParams,
+ type CustomerProfileUpdateParams as CustomerProfileUpdateParams,
+ };
+
+ export { Billing as Billing, type BillingRetrieveResponse as BillingRetrieveResponse };
+}
diff --git a/src/resources/customer-profiles/index.ts b/src/resources/customer-profiles/index.ts
new file mode 100644
index 00000000..e730e70b
--- /dev/null
+++ b/src/resources/customer-profiles/index.ts
@@ -0,0 +1,11 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export { Billing, type BillingRetrieveResponse } from './billing';
+export {
+ CustomerProfiles,
+ type CustomerProfileCreateResponse,
+ type CustomerProfileRetrieveResponse,
+ type CustomerProfileUpdateResponse,
+ type CustomerProfileCreateParams,
+ type CustomerProfileUpdateParams,
+} from './customer-profiles';
diff --git a/src/resources/index.ts b/src/resources/index.ts
index cbac5671..2dccd080 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -3,5 +3,31 @@
export {
CustomerProfiles,
type CustomerProfileCreateResponse,
+ type CustomerProfileRetrieveResponse,
+ type CustomerProfileUpdateResponse,
type CustomerProfileCreateParams,
-} from './customer-profiles';
+ type CustomerProfileUpdateParams,
+} from './customer-profiles/customer-profiles';
+export {
+ Products,
+ type ProductCreateResponse,
+ type ProductUpdateResponse,
+ type ProductListResponse,
+ type ProductCreateParams,
+ type ProductUpdateParams,
+ type ProductListParams,
+} from './products';
+export {
+ PurchaseSessions,
+ type PurchaseSessionCreateResponse,
+ type PurchaseSessionCreateParams,
+} from './purchase-sessions';
+export {
+ Variants,
+ type VariantCreateResponse,
+ type VariantUpdateResponse,
+ type VariantListResponse,
+ type VariantCreateParams,
+ type VariantUpdateParams,
+ type VariantListParams,
+} from './variants';
diff --git a/src/resources/products.ts b/src/resources/products.ts
new file mode 100644
index 00000000..34a67f10
--- /dev/null
+++ b/src/resources/products.ts
@@ -0,0 +1,682 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../resource';
+import { isRequestOptions } from '../core';
+import * as Core from '../core';
+
+export class Products extends APIResource {
+ /**
+ * Create products
+ */
+ create(body: ProductCreateParams, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post('/api/v1/products', { body, ...options });
+ }
+
+ /**
+ * Update products
+ */
+ update(
+ id: string,
+ body: ProductUpdateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.put(`/api/v1/products/${id}`, { body, ...options });
+ }
+
+ /**
+ * List products
+ */
+ list(query?: ProductListParams, options?: Core.RequestOptions): Core.APIPromise;
+ list(options?: Core.RequestOptions): Core.APIPromise;
+ list(
+ query: ProductListParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(query)) {
+ return this.list({}, query);
+ }
+ return this._client.get('/api/v1/products', { query, ...options });
+ }
+}
+
+export interface ProductCreateResponse {
+ product: ProductCreateResponse.Product;
+}
+
+export namespace ProductCreateResponse {
+ export interface Product {
+ id: string;
+
+ active: boolean;
+
+ /**
+ * safeZodDate
+ */
+ createdAt: string | string;
+
+ description: string | null;
+
+ imageURL: string | null;
+
+ livemode: boolean;
+
+ name: string;
+
+ OrganizationId: string;
+
+ type: 'service' | 'digital' | (string & {});
+
+ /**
+ * safeZodDate
+ */
+ updatedAt: string | string;
+ }
+}
+
+export interface ProductUpdateResponse {
+ product: ProductUpdateResponse.Product;
+}
+
+export namespace ProductUpdateResponse {
+ export interface Product {
+ id: string;
+
+ active: boolean;
+
+ /**
+ * safeZodDate
+ */
+ createdAt: string | string;
+
+ description: string | null;
+
+ imageURL: string | null;
+
+ livemode: boolean;
+
+ name: string;
+
+ OrganizationId: string;
+
+ type: 'service' | 'digital' | (string & {});
+
+ /**
+ * safeZodDate
+ */
+ updatedAt: string | string;
+ }
+}
+
+export type ProductListResponse = Array;
+
+export namespace ProductListResponse {
+ export interface ProductListResponseItem {
+ product: ProductListResponseItem.Product;
+
+ variant: ProductListResponseItem.SubscriptionVariant | ProductListResponseItem.SinglePaymentVariant;
+ }
+
+ export namespace ProductListResponseItem {
+ export interface Product {
+ id: string;
+
+ active: boolean;
+
+ /**
+ * safeZodDate
+ */
+ createdAt: string | string;
+
+ description: string | null;
+
+ imageURL: string | null;
+
+ livemode: boolean;
+
+ name: string;
+
+ OrganizationId: string;
+
+ type: 'service' | 'digital' | (string & {});
+
+ /**
+ * safeZodDate
+ */
+ updatedAt: string | string;
+ }
+
+ export interface SubscriptionVariant {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year';
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+ }
+
+ export interface SinglePaymentVariant {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+ }
+}
+
+export interface ProductCreateParams {
+ offerings: Array<
+ | ProductCreateParams.FileOffering
+ | ProductCreateParams.CommunityOffering
+ | ProductCreateParams.LinkOffering
+ >;
+
+ product: ProductCreateParams.Product;
+
+ variant: ProductCreateParams.SubscriptionVariant | ProductCreateParams.SinglePaymentVariant;
+}
+
+export namespace ProductCreateParams {
+ export interface FileOffering {
+ file: File;
+
+ type: 'file';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface File {
+ id: string | null;
+
+ name: string;
+
+ objectKey: string;
+
+ ProductId?: string | null;
+ }
+
+ export interface CommunityOffering {
+ community: Community;
+
+ type: 'community';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface Community {
+ id: string | null;
+
+ name: string;
+
+ platform: 'discord' | 'slack' | (string & {});
+
+ IntegrationId?: string | null;
+
+ inviteURL?: string | null;
+
+ platformId?: string | null;
+
+ ProductId?: string | null;
+ }
+
+ export interface LinkOffering {
+ link: Link;
+
+ type: 'link';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface Link {
+ id: string | null;
+
+ name: string;
+
+ url: string;
+
+ ProductId?: string | null;
+ }
+
+ export interface Product {
+ name: string;
+
+ type: 'service' | 'digital' | (string & {});
+
+ active?: boolean;
+
+ description?: string | null;
+
+ imageURL?: string | null;
+ }
+
+ export interface SubscriptionVariant {
+ active: boolean;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year';
+
+ isDefault: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+ }
+
+ export interface SinglePaymentVariant {
+ active: boolean;
+
+ isDefault: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+}
+
+export interface ProductUpdateParams {
+ offerings: Array<
+ | ProductUpdateParams.FileOffering
+ | ProductUpdateParams.LinkOffering
+ | ProductUpdateParams.CommunityOffering
+ >;
+
+ product: ProductUpdateParams.Product;
+
+ variant: ProductUpdateParams.SubscriptionVariant | ProductUpdateParams.SinglePaymentVariant;
+}
+
+export namespace ProductUpdateParams {
+ export interface FileOffering {
+ file: File;
+
+ type: 'file';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface File {
+ id: string | null;
+
+ name: string;
+
+ objectKey: string;
+
+ ProductId?: string | null;
+ }
+
+ export interface CommunityOffering {
+ community: Community;
+
+ type: 'community';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface Community {
+ id: string | null;
+
+ name: string;
+
+ platform: 'discord' | 'slack' | (string & {});
+
+ IntegrationId?: string | null;
+
+ inviteURL?: string | null;
+
+ platformId?: string | null;
+
+ ProductId?: string | null;
+ }
+
+ export interface LinkOffering {
+ link: Link;
+
+ type: 'link';
+
+ id?: string | null;
+
+ createdAt?: string;
+
+ livemode?: boolean;
+
+ OfferableId?: string | null;
+
+ order?: number | null;
+
+ OrganizationId?: string;
+
+ ProductId?: string | null;
+
+ updatedAt?: string | null;
+
+ VariantId?: string | null;
+ }
+
+ export interface Link {
+ id: string | null;
+
+ name: string;
+
+ url: string;
+
+ ProductId?: string | null;
+ }
+
+ export interface Product {
+ id: string;
+
+ active?: boolean;
+
+ defaultStripePriceId?: string | null;
+
+ description?: string | null;
+
+ imageURL?: string | null;
+
+ livemode?: boolean;
+
+ name?: string;
+
+ OrganizationId?: string;
+
+ stripeProductId?: string | null;
+
+ type?: 'service' | 'digital' | (string & {});
+ }
+
+ export interface SubscriptionVariant {
+ id: string;
+
+ priceType: 'subscription';
+
+ active?: boolean;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount?: string | number;
+
+ intervalUnit?: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault?: boolean;
+
+ livemode?: boolean;
+
+ name?: string | null;
+
+ ProductId?: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount?: string | number | 0 | null;
+
+ stripePriceId?: string | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays?: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice?: string | number;
+ }
+
+ export interface SinglePaymentVariant {
+ id: string;
+
+ priceType: 'single_payment';
+
+ active?: boolean;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ isDefault?: boolean;
+
+ livemode?: boolean;
+
+ name?: string | null;
+
+ ProductId?: string;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ stripePriceId?: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice?: string | number;
+ }
+}
+
+export interface ProductListParams {
+ active?: boolean;
+}
+
+export declare namespace Products {
+ export {
+ type ProductCreateResponse as ProductCreateResponse,
+ type ProductUpdateResponse as ProductUpdateResponse,
+ type ProductListResponse as ProductListResponse,
+ type ProductCreateParams as ProductCreateParams,
+ type ProductUpdateParams as ProductUpdateParams,
+ type ProductListParams as ProductListParams,
+ };
+}
diff --git a/src/resources/purchase-sessions.ts b/src/resources/purchase-sessions.ts
new file mode 100644
index 00000000..5a00713e
--- /dev/null
+++ b/src/resources/purchase-sessions.ts
@@ -0,0 +1,99 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../resource';
+import * as Core from '../core';
+
+export class PurchaseSessions extends APIResource {
+ /**
+ * Create purchaseSessions
+ */
+ create(
+ body: PurchaseSessionCreateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.post('/api/v1/purchase-sessions', { body, ...options });
+ }
+}
+
+export interface PurchaseSessionCreateResponse {
+ purchaseSession: PurchaseSessionCreateResponse.PurchaseSession;
+}
+
+export namespace PurchaseSessionCreateResponse {
+ export interface PurchaseSession {
+ id: string;
+
+ billingAddress: PurchaseSession.BillingAddress | null;
+
+ /**
+ * safeZodDate
+ */
+ createdAt: string | string;
+
+ customerEmail: string | null;
+
+ customerName: string | null;
+
+ CustomerProfileId: string | null;
+
+ DiscountId: string | null;
+
+ livemode: boolean;
+
+ OrganizationId: string;
+
+ paymentMethodType: 'card' | 'us_bank_account' | 'sepa_debit' | (string & {}) | null;
+
+ PurchaseId: string | null;
+
+ /**
+ * safeZodDate
+ */
+ updatedAt: string | string | null;
+
+ VariantId: string;
+ }
+
+ export namespace PurchaseSession {
+ export interface BillingAddress {
+ address: BillingAddress.Address;
+
+ name: string;
+
+ firstName?: string;
+
+ lastName?: string;
+
+ phone?: string;
+ }
+
+ export namespace BillingAddress {
+ export interface Address {
+ city: string;
+
+ country: string;
+
+ line1: string;
+
+ line2: string | null;
+
+ postal_code: string;
+
+ state: string;
+ }
+ }
+ }
+}
+
+export interface PurchaseSessionCreateParams {
+ customerProfileExternalId: string;
+
+ VariantId: string;
+}
+
+export declare namespace PurchaseSessions {
+ export {
+ type PurchaseSessionCreateResponse as PurchaseSessionCreateResponse,
+ type PurchaseSessionCreateParams as PurchaseSessionCreateParams,
+ };
+}
diff --git a/src/resources/variants.ts b/src/resources/variants.ts
new file mode 100644
index 00000000..f649b234
--- /dev/null
+++ b/src/resources/variants.ts
@@ -0,0 +1,508 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../resource';
+import { isRequestOptions } from '../core';
+import * as Core from '../core';
+
+export class Variants extends APIResource {
+ /**
+ * Create variants
+ */
+ create(body: VariantCreateParams, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post('/api/v1/variants', { body, ...options });
+ }
+
+ /**
+ * Update variants
+ */
+ update(
+ id: string,
+ body: VariantUpdateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.put(`/api/v1/variants/${id}`, { body, ...options });
+ }
+
+ /**
+ * List variants
+ */
+ list(query?: VariantListParams, options?: Core.RequestOptions): Core.APIPromise;
+ list(options?: Core.RequestOptions): Core.APIPromise;
+ list(
+ query: VariantListParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(query)) {
+ return this.list({}, query);
+ }
+ return this._client.get('/api/v1/variants', { query, ...options });
+ }
+}
+
+export interface VariantCreateResponse {
+ variant: VariantCreateResponse.UnionMember0 | VariantCreateResponse.UnionMember1;
+}
+
+export namespace VariantCreateResponse {
+ export interface UnionMember0 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+ }
+
+ export interface UnionMember1 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+}
+
+export interface VariantUpdateResponse {
+ variant: VariantUpdateResponse.UnionMember0 | VariantUpdateResponse.UnionMember1;
+}
+
+export namespace VariantUpdateResponse {
+ export interface UnionMember0 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+ }
+
+ export interface UnionMember1 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+}
+
+export interface VariantListResponse {
+ variants: Array;
+}
+
+export namespace VariantListResponse {
+ export interface UnionMember0 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+ }
+
+ export interface UnionMember1 {
+ id: string;
+
+ active: boolean;
+
+ createdAt: string;
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ updatedAt: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+}
+
+export interface VariantCreateParams {
+ variant: VariantCreateParams.UnionMember0 | VariantCreateParams.UnionMember1;
+}
+
+export namespace VariantCreateParams {
+ export interface UnionMember0 {
+ active: boolean;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount: string | number;
+
+ intervalUnit: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'subscription';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ stripePriceId?: string | null;
+ }
+
+ export interface UnionMember1 {
+ active: boolean;
+
+ isDefault: boolean;
+
+ livemode: boolean;
+
+ name: string | null;
+
+ priceType: 'single_payment';
+
+ ProductId: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice: string | number;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ stripePriceId?: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+ }
+}
+
+export interface VariantUpdateParams {
+ variant: VariantUpdateParams.UnionMember0 | VariantUpdateParams.UnionMember1;
+}
+
+export namespace VariantUpdateParams {
+ export interface UnionMember0 {
+ id: string;
+
+ priceType: 'subscription';
+
+ active?: boolean;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ intervalCount?: string | number;
+
+ intervalUnit?: 'day' | 'week' | 'month' | 'year' | (string & {});
+
+ isDefault?: boolean;
+
+ livemode?: boolean;
+
+ name?: string | null;
+
+ ProductId?: string;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ setupFeeAmount?: string | number | 0 | null;
+
+ stripePriceId?: string | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ trialPeriodDays?: string | number | 0 | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice?: string | number;
+ }
+
+ export interface UnionMember1 {
+ id: string;
+
+ priceType: 'single_payment';
+
+ active?: boolean;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalCount?: unknown | unknown | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ intervalUnit?: unknown | unknown | null;
+
+ isDefault?: boolean;
+
+ livemode?: boolean;
+
+ name?: string | null;
+
+ ProductId?: string;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ setupFeeAmount?: unknown | unknown | null;
+
+ stripePriceId?: string | null;
+
+ /**
+ * safeZodNullOrUndefined
+ */
+ trialPeriodDays?: unknown | unknown | null;
+
+ /**
+ * safeZodPositiveInteger
+ */
+ unitPrice?: string | number;
+ }
+}
+
+export interface VariantListParams {
+ ProductId?: string;
+}
+
+export declare namespace Variants {
+ export {
+ type VariantCreateResponse as VariantCreateResponse,
+ type VariantUpdateResponse as VariantUpdateResponse,
+ type VariantListResponse as VariantListResponse,
+ type VariantCreateParams as VariantCreateParams,
+ type VariantUpdateParams as VariantUpdateParams,
+ type VariantListParams as VariantListParams,
+ };
+}
diff --git a/src/version.ts b/src/version.ts
index db692bc9..b0bfd9e7 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.0.1-alpha.0'; // x-release-please-version
+export const VERSION = '0.1.0-alpha.1'; // x-release-please-version
diff --git a/tests/api-resources/customer-profiles/billing.test.ts b/tests/api-resources/customer-profiles/billing.test.ts
new file mode 100644
index 00000000..c53b4abd
--- /dev/null
+++ b/tests/api-resources/customer-profiles/billing.test.ts
@@ -0,0 +1,29 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Flowglad from '@flowglad/node';
+import { Response } from 'node-fetch';
+
+const client = new Flowglad({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource billing', () => {
+ test('retrieve', async () => {
+ const responsePromise = client.customerProfiles.billing.retrieve('externalId');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieve: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.customerProfiles.billing.retrieve('externalId', { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Flowglad.NotFoundError);
+ });
+});
diff --git a/tests/api-resources/customer-profiles/customer-profiles.test.ts b/tests/api-resources/customer-profiles/customer-profiles.test.ts
new file mode 100644
index 00000000..4be5e1a1
--- /dev/null
+++ b/tests/api-resources/customer-profiles/customer-profiles.test.ts
@@ -0,0 +1,82 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Flowglad from '@flowglad/node';
+import { Response } from 'node-fetch';
+
+const client = new Flowglad({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource customerProfiles', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.customerProfiles.create({
+ customerProfile: { email: 'email', externalId: 'externalId' },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: required and optional params', async () => {
+ const response = await client.customerProfiles.create({
+ customerProfile: {
+ email: 'email',
+ externalId: 'externalId',
+ archived: true,
+ domain: 'domain',
+ iconURL: 'iconURL',
+ logoURL: 'logoURL',
+ name: 'name',
+ },
+ });
+ });
+
+ test('retrieve', async () => {
+ const responsePromise = client.customerProfiles.retrieve('externalId');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieve: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.customerProfiles.retrieve('externalId', { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Flowglad.NotFoundError);
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.customerProfiles.update('externalId', { customerProfile: { id: 'id' } });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: required and optional params', async () => {
+ const response = await client.customerProfiles.update('externalId', {
+ customerProfile: {
+ id: 'id',
+ archived: true,
+ domain: 'domain',
+ email: 'email',
+ externalId: 'externalId',
+ iconURL: 'iconURL',
+ logoURL: 'logoURL',
+ name: 'name',
+ },
+ });
+ });
+});
diff --git a/tests/api-resources/products.test.ts b/tests/api-resources/products.test.ts
new file mode 100644
index 00000000..77fccbb2
--- /dev/null
+++ b/tests/api-resources/products.test.ts
@@ -0,0 +1,163 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Flowglad from '@flowglad/node';
+import { Response } from 'node-fetch';
+
+const client = new Flowglad({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource products', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.products.create({
+ offerings: [{ file: { id: 'id', name: 'name', objectKey: 'objectKey' }, type: 'file' }],
+ product: { name: 'name', type: 'service' },
+ variant: {
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ name: 'name',
+ priceType: 'subscription',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: required and optional params', async () => {
+ const response = await client.products.create({
+ offerings: [
+ {
+ file: { id: 'id', name: 'name', objectKey: 'objectKey', ProductId: 'ProductId' },
+ type: 'file',
+ id: 'id',
+ createdAt: '2019-12-27T18:11:19.117Z',
+ livemode: true,
+ OfferableId: 'OfferableId',
+ order: 0,
+ OrganizationId: 'OrganizationId',
+ ProductId: 'ProductId',
+ updatedAt: '2019-12-27T18:11:19.117Z',
+ VariantId: 'VariantId',
+ },
+ ],
+ product: {
+ name: 'name',
+ type: 'service',
+ active: true,
+ description: 'description',
+ imageURL: 'imageURL',
+ },
+ variant: {
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ name: 'name',
+ priceType: 'subscription',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ },
+ });
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.products.update('id', {
+ offerings: [{ file: { id: 'id', name: 'name', objectKey: 'objectKey' }, type: 'file' }],
+ product: { id: 'id' },
+ variant: { id: 'id', priceType: 'subscription' },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: required and optional params', async () => {
+ const response = await client.products.update('id', {
+ offerings: [
+ {
+ file: { id: 'id', name: 'name', objectKey: 'objectKey', ProductId: 'ProductId' },
+ type: 'file',
+ id: 'id',
+ createdAt: '2019-12-27T18:11:19.117Z',
+ livemode: true,
+ OfferableId: 'OfferableId',
+ order: 0,
+ OrganizationId: 'OrganizationId',
+ ProductId: 'ProductId',
+ updatedAt: '2019-12-27T18:11:19.117Z',
+ VariantId: 'VariantId',
+ },
+ ],
+ product: {
+ id: 'id',
+ active: true,
+ defaultStripePriceId: 'defaultStripePriceId',
+ description: 'description',
+ imageURL: 'imageURL',
+ livemode: true,
+ name: 'name',
+ OrganizationId: 'OrganizationId',
+ stripeProductId: 'stripeProductId',
+ type: 'service',
+ },
+ variant: {
+ id: 'id',
+ priceType: 'subscription',
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ livemode: true,
+ name: 'name',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ stripePriceId: 'stripePriceId',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ },
+ });
+ });
+
+ test('list', async () => {
+ const responsePromise = client.products.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.products.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Flowglad.NotFoundError,
+ );
+ });
+
+ test('list: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.products.list({ active: true }, { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Flowglad.NotFoundError);
+ });
+});
diff --git a/tests/api-resources/customer-profiles.test.ts b/tests/api-resources/purchase-sessions.test.ts
similarity index 53%
rename from tests/api-resources/customer-profiles.test.ts
rename to tests/api-resources/purchase-sessions.test.ts
index 247976e7..7355a78c 100644
--- a/tests/api-resources/customer-profiles.test.ts
+++ b/tests/api-resources/purchase-sessions.test.ts
@@ -8,10 +8,11 @@ const client = new Flowglad({
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
});
-describe('resource customerProfiles', () => {
+describe('resource purchaseSessions', () => {
test('create: only required params', async () => {
- const responsePromise = client.customerProfiles.create({
- customerProfile: { CustomerId: 'CustomerId', email: 'email', OrganizationId: 'OrganizationId' },
+ const responsePromise = client.purchaseSessions.create({
+ customerProfileExternalId: 'customerProfileExternalId',
+ VariantId: 'VariantId',
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
@@ -23,22 +24,9 @@ describe('resource customerProfiles', () => {
});
test('create: required and optional params', async () => {
- const response = await client.customerProfiles.create({
- customerProfile: {
- CustomerId: 'CustomerId',
- email: 'email',
- OrganizationId: 'OrganizationId',
- archived: true,
- customerTaxId: 'customerTaxId',
- domain: 'domain',
- iconURL: 'iconURL',
- invoiceNumberBase: 'invoiceNumberBase',
- livemode: true,
- logoURL: 'logoURL',
- name: 'name',
- slackId: 'slackId',
- stripeCustomerId: 'stripeCustomerId',
- },
+ const response = await client.purchaseSessions.create({
+ customerProfileExternalId: 'customerProfileExternalId',
+ VariantId: 'VariantId',
});
});
});
diff --git a/tests/api-resources/variants.test.ts b/tests/api-resources/variants.test.ts
new file mode 100644
index 00000000..d866175d
--- /dev/null
+++ b/tests/api-resources/variants.test.ts
@@ -0,0 +1,113 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Flowglad from '@flowglad/node';
+import { Response } from 'node-fetch';
+
+const client = new Flowglad({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource variants', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.variants.create({
+ variant: {
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ livemode: true,
+ name: 'name',
+ priceType: 'subscription',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: required and optional params', async () => {
+ const response = await client.variants.create({
+ variant: {
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ livemode: true,
+ name: 'name',
+ priceType: 'subscription',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ stripePriceId: 'stripePriceId',
+ },
+ });
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.variants.update('id', {
+ variant: { id: 'id', priceType: 'subscription' },
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('update: required and optional params', async () => {
+ const response = await client.variants.update('id', {
+ variant: {
+ id: 'id',
+ priceType: 'subscription',
+ active: true,
+ intervalCount: 'string',
+ intervalUnit: 'day',
+ isDefault: true,
+ livemode: true,
+ name: 'name',
+ ProductId: 'ProductId',
+ setupFeeAmount: 'string',
+ stripePriceId: 'stripePriceId',
+ trialPeriodDays: 'string',
+ unitPrice: 'string',
+ },
+ });
+ });
+
+ test('list', async () => {
+ const responsePromise = client.variants.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.variants.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Flowglad.NotFoundError,
+ );
+ });
+
+ test('list: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.variants.list({ ProductId: 'ProductId' }, { path: '/_stainless_unknown_path' }),
+ ).rejects.toThrow(Flowglad.NotFoundError);
+ });
+});
diff --git a/tests/index.test.ts b/tests/index.test.ts
index ce831a37..30e15bc5 100644
--- a/tests/index.test.ts
+++ b/tests/index.test.ts
@@ -96,6 +96,15 @@ describe('instantiate client', () => {
expect(response).toEqual({ url: 'http://localhost:5000/foo', custom: true });
});
+ test('explicit global fetch', async () => {
+ // make sure the global fetch type is assignable to our Fetch type
+ const client = new Flowglad({
+ baseURL: 'http://localhost:5000/',
+ apiKey: 'My API Key',
+ fetch: defaultFetch,
+ });
+ });
+
test('custom signal', async () => {
const client = new Flowglad({
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
@@ -168,13 +177,26 @@ describe('instantiate client', () => {
test('empty env variable', () => {
process.env['FLOWGLAD_BASE_URL'] = ''; // empty
const client = new Flowglad({ apiKey: 'My API Key' });
- expect(client.baseURL).toEqual('http://localhost:3000/');
+ expect(client.baseURL).toEqual('https://app.flowglad.com/api/v1');
});
test('blank env variable', () => {
process.env['FLOWGLAD_BASE_URL'] = ' '; // blank
const client = new Flowglad({ apiKey: 'My API Key' });
- expect(client.baseURL).toEqual('http://localhost:3000/');
+ expect(client.baseURL).toEqual('https://app.flowglad.com/api/v1');
+ });
+
+ test('env variable with environment', () => {
+ process.env['FLOWGLAD_BASE_URL'] = 'https://example.com/from_env';
+
+ expect(
+ () => new Flowglad({ apiKey: 'My API Key', environment: 'production' }),
+ ).toThrowErrorMatchingInlineSnapshot(
+ `"Ambiguous URL; The \`baseURL\` option (or FLOWGLAD_BASE_URL env var) and the \`environment\` option are given. If you want to use the environment you must pass baseURL: null"`,
+ );
+
+ const client = new Flowglad({ apiKey: 'My API Key', baseURL: null, environment: 'production' });
+ expect(client.baseURL).toEqual('https://app.flowglad.com/api/v1');
});
});
@@ -189,14 +211,14 @@ describe('instantiate client', () => {
test('with environment variable arguments', () => {
// set options via env var
- process.env['FLOWGLAD_API_KEY'] = 'My API Key';
+ process.env['FLOWGLAD_SECRET_KEY'] = 'My API Key';
const client = new Flowglad();
expect(client.apiKey).toBe('My API Key');
});
test('with overridden environment variable arguments', () => {
// set options via env var
- process.env['FLOWGLAD_API_KEY'] = 'another My API Key';
+ process.env['FLOWGLAD_SECRET_KEY'] = 'another My API Key';
const client = new Flowglad({ apiKey: 'My API Key' });
expect(client.apiKey).toBe('My API Key');
});