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'); });