From ab1bfe8705631f229c10ac023bc8ae205c4edd46 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 06:44:42 +0000 Subject: [PATCH 01/33] chore(ci): upgrade `actions/github-script` --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c19ecfb..66ef3d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/flowglad-typescript' id: github-oidc - uses: actions/github-script@v6 + uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); From 56900bed3729ab2a7f4d872fad1692a888cbf802 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 08:16:47 +0000 Subject: [PATCH 02/33] fix(client): avoid memory leak with abort signals --- src/client.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 173cb9c..3e33f69 100644 --- a/src/client.ts +++ b/src/client.ts @@ -628,9 +628,10 @@ export class Flowglad { controller: AbortController, ): Promise { const { signal, method, ...options } = init || {}; - if (signal) signal.addEventListener('abort', () => controller.abort()); + const abort = controller.abort.bind(controller); + if (signal) signal.addEventListener('abort', abort, { once: true }); - const timeout = setTimeout(() => controller.abort(), ms); + const timeout = setTimeout(abort, ms); const isReadableBody = ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || From fdf283447a556e939343febecc89663c4b2ac9e6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 08:19:25 +0000 Subject: [PATCH 03/33] chore(client): do not parse responses with empty content-length --- src/internal/parse.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 9b5eabc..6e3092e 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -29,6 +29,12 @@ export async function defaultParseResponse(client: Flowglad, props: APIRespon const mediaType = contentType?.split(';')[0]?.trim(); const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); if (isJSON) { + const contentLength = response.headers.get('content-length'); + if (contentLength === '0') { + // if there is no content we can't do anything + return undefined as T; + } + const json = await response.json(); return json as T; } From 55978f2f8d4ece515b0613b7e47833a5dd7c1a84 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 05:42:50 +0000 Subject: [PATCH 04/33] chore(client): restructure abort controller binding --- src/client.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 3e33f69..c75a767 100644 --- a/src/client.ts +++ b/src/client.ts @@ -628,7 +628,7 @@ export class Flowglad { controller: AbortController, ): Promise { const { signal, method, ...options } = init || {}; - const abort = controller.abort.bind(controller); + const abort = this._makeAbort(controller); if (signal) signal.addEventListener('abort', abort, { once: true }); const timeout = setTimeout(abort, ms); @@ -654,6 +654,7 @@ export class Flowglad { return await this.fetch.call(undefined, url, fetchOptions); } finally { clearTimeout(timeout); + if (signal) signal.removeEventListener('abort', abort); } } @@ -798,6 +799,12 @@ export class Flowglad { return headers.values; } + private _makeAbort(controller: AbortController) { + // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure + // would capture all request options, and cause a memory leak. + return () => controller.abort(); + } + private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): { bodyHeaders: HeadersLike; body: BodyInit | undefined; From d98d3e7d87551397703c141d873e8b4234a8a889 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 08:09:56 +0000 Subject: [PATCH 05/33] fix(types): correctly define false enum --- src/resources/checkout-sessions.ts | 4 +- src/resources/customers.ts | 26 ++++++------ src/resources/payments.ts | 2 +- src/resources/prices.ts | 16 ++++---- src/resources/products.ts | 16 ++++---- src/resources/shared.ts | 2 +- src/resources/subscriptions.ts | 40 +++++++++---------- tests/api-resources/checkout-sessions.test.ts | 2 +- 8 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/resources/checkout-sessions.ts b/src/resources/checkout-sessions.ts index b1e18e0..5e0db32 100644 --- a/src/resources/checkout-sessions.ts +++ b/src/resources/checkout-sessions.ts @@ -323,7 +323,7 @@ export interface PurchaseCheckoutSessionClientSelectSchema { paymentMethodType?: 'card' | 'link' | 'us_bank_account' | 'sepa_debit' | null; - preserveBillingCycleAnchor?: boolean; + preserveBillingCycleAnchor?: false; successUrl?: string | null; @@ -411,7 +411,7 @@ export namespace CheckoutSessionCreateParams { type: 'product'; - anonymous?: boolean; + anonymous?: false; /** * JSON object diff --git a/src/resources/customers.ts b/src/resources/customers.ts index 311ea94..57791cf 100644 --- a/src/resources/customers.ts +++ b/src/resources/customers.ts @@ -149,7 +149,7 @@ export interface NonRenewingSubscriptionDetails { pricingModelId: string; - renews: boolean; + renews: false; replacedBySubscriptionId: string | null; @@ -226,13 +226,13 @@ export namespace NonRenewingSubscriptionDetails { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -506,13 +506,13 @@ export namespace StandardSubscriptionDetails { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -789,13 +789,13 @@ export namespace CustomerCreateResponse { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -907,7 +907,7 @@ export namespace CustomerRetrieveBillingResponse { customerId: string; - firstInvoiceValue: number; + firstInvoiceValue: 0; /** * A positive integer @@ -949,7 +949,7 @@ export namespace CustomerRetrieveBillingResponse { */ totalPurchaseValue: null; - trialPeriodDays: number; + trialPeriodDays: 0; /** * Epoch milliseconds. @@ -993,7 +993,7 @@ export namespace CustomerRetrieveBillingResponse { customerId: string; - firstInvoiceValue: number; + firstInvoiceValue: 0; /** * Omitted. @@ -1033,7 +1033,7 @@ export namespace CustomerRetrieveBillingResponse { status: 'open' | 'pending' | 'failed' | 'paid' | 'refunded' | 'partial_refund' | 'fraudulent'; - totalPurchaseValue: number; + totalPurchaseValue: 0; /** * Omitted. @@ -1082,7 +1082,7 @@ export namespace CustomerRetrieveBillingResponse { customerId: string; - firstInvoiceValue: number; + firstInvoiceValue: 0; /** * Omitted. @@ -1122,7 +1122,7 @@ export namespace CustomerRetrieveBillingResponse { status: 'open' | 'pending' | 'failed' | 'paid' | 'refunded' | 'partial_refund' | 'fraudulent'; - totalPurchaseValue: number; + totalPurchaseValue: 0; /** * Omitted. diff --git a/src/resources/payments.ts b/src/resources/payments.ts index dd679a1..778bc4e 100644 --- a/src/resources/payments.ts +++ b/src/resources/payments.ts @@ -34,7 +34,7 @@ export class Payments extends APIResource { export interface PaymentClientSelectSchema { id: string; - amount: number; + amount: 0; applicationFee: number | null; diff --git a/src/resources/prices.ts b/src/resources/prices.ts index b833bd8..5acb924 100644 --- a/src/resources/prices.ts +++ b/src/resources/prices.ts @@ -207,7 +207,7 @@ export interface SinglePaymentPriceClientSelectSchema { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -423,7 +423,7 @@ export interface SubscriptionPriceClientSelectSchema { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -444,7 +444,7 @@ export interface SubscriptionPriceClientSelectSchema { * The trial period in days. If the trial period is 0 or null, there will be no * trial period. */ - trialPeriodDays?: number | null; + trialPeriodDays?: 0 | null; } export interface UsagePriceClientSelectSchema { @@ -632,7 +632,7 @@ export interface UsagePriceClientSelectSchema { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -715,7 +715,7 @@ export namespace PriceCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -727,7 +727,7 @@ export namespace PriceCreateParams { * The trial period in days. If the trial period is 0 or null, there will be no * trial period. */ - trialPeriodDays?: number | null; + trialPeriodDays?: 0 | null; /** * Omitted. @@ -760,7 +760,7 @@ export namespace PriceCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -816,7 +816,7 @@ export namespace PriceCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * The number of usage events per unit. Used to determine how to map usage events diff --git a/src/resources/products.ts b/src/resources/products.ts index 6d4066f..370045c 100644 --- a/src/resources/products.ts +++ b/src/resources/products.ts @@ -230,7 +230,7 @@ export namespace ProductCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -242,7 +242,7 @@ export namespace ProductCreateParams { * The trial period in days. If the trial period is 0 or null, there will be no * trial period. */ - trialPeriodDays?: number | null; + trialPeriodDays?: 0 | null; /** * Omitted. @@ -270,7 +270,7 @@ export namespace ProductCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -326,7 +326,7 @@ export namespace ProductCreateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * The number of usage events per unit. Used to determine how to map usage events @@ -436,7 +436,7 @@ export namespace ProductUpdateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -448,7 +448,7 @@ export namespace ProductUpdateParams { * The trial period in days. If the trial period is 0 or null, there will be no * trial period. */ - trialPeriodDays?: number | null; + trialPeriodDays?: 0 | null; /** * Omitted. @@ -481,7 +481,7 @@ export namespace ProductUpdateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; active?: boolean; @@ -537,7 +537,7 @@ export namespace ProductUpdateParams { * example, if the currency is USD, GBP, CAD, EUR or SGD, the price should be in * cents. */ - unitPrice: number; + unitPrice: 0; /** * The number of usage events per unit. Used to determine how to map usage events diff --git a/src/resources/shared.ts b/src/resources/shared.ts index 434565e..2408d49 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -96,7 +96,7 @@ export interface NonRenewingSubscriptionRecord { pricingModelId: string; - renews: boolean; + renews: false; replacedBySubscriptionId: string | null; diff --git a/src/resources/subscriptions.ts b/src/resources/subscriptions.ts index a99d04e..eee60ff 100644 --- a/src/resources/subscriptions.ts +++ b/src/resources/subscriptions.ts @@ -136,13 +136,13 @@ export namespace SubscriptionAdjustResponse { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -303,13 +303,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for @@ -357,13 +357,13 @@ export namespace SubscriptionAdjustParams { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -389,13 +389,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for @@ -467,13 +467,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for @@ -521,13 +521,13 @@ export namespace SubscriptionAdjustParams { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -553,13 +553,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for @@ -640,13 +640,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for @@ -694,13 +694,13 @@ export namespace SubscriptionAdjustParams { pricingModelId: string; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Epoch milliseconds. @@ -726,13 +726,13 @@ export namespace SubscriptionAdjustParams { */ addedDate: number; - quantity: number; + quantity: 0; subscriptionId: string; type: 'static'; - unitPrice: number; + unitPrice: 0; /** * Used as a flag to soft delete a subscription item without losing its history for diff --git a/tests/api-resources/checkout-sessions.test.ts b/tests/api-resources/checkout-sessions.test.ts index 043bc3c..243549f 100644 --- a/tests/api-resources/checkout-sessions.test.ts +++ b/tests/api-resources/checkout-sessions.test.ts @@ -35,7 +35,7 @@ describe('resource checkoutSessions', () => { customerExternalId: 'customerExternalId', successUrl: 'successUrl', type: 'product', - anonymous: true, + anonymous: false, outputMetadata: { foo: 'string' }, outputName: 'outputName', preserveBillingCycleAnchor: true, From db6b522ba19e11051a8d26be9905d8a88796d455 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 08:11:40 +0000 Subject: [PATCH 06/33] fix(client): avoid removing abort listener too early --- src/client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index c75a767..f3bc9ba 100644 --- a/src/client.ts +++ b/src/client.ts @@ -654,7 +654,6 @@ export class Flowglad { return await this.fetch.call(undefined, url, fetchOptions); } finally { clearTimeout(timeout); - if (signal) signal.removeEventListener('abort', abort); } } From a460ca893ece9bf09c768db7fd3122c5b60d7caa Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 08:52:32 +0000 Subject: [PATCH 07/33] chore(internal): avoid type checking errors with ts-reset --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index f3bc9ba..983c4d4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -587,7 +587,7 @@ export class Flowglad { loggerFor(this).info(`${responseInfo} - ${retryMessage}`); const errText = await response.text().catch((err: any) => castToError(err).message); - const errJSON = safeJSON(errText); + const errJSON = safeJSON(errText) as any; const errMessage = errJSON ? undefined : errText; loggerFor(this).debug( From a7577d3c4b321509d224b71464e184e8df875888 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 06:21:20 +0000 Subject: [PATCH 08/33] chore(internal/client): fix form-urlencoded requests --- src/client.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/client.ts b/src/client.ts index 983c4d4..7402a0b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -836,6 +836,14 @@ export class Flowglad { (Symbol.iterator in body && 'next' in body && typeof body.next === 'function')) ) { return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body as AsyncIterable) }; + } else if ( + typeof body === 'object' && + headers.values.get('content-type') === 'application/x-www-form-urlencoded' + ) { + return { + bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' }, + body: this.stringifyQuery(body as Record), + }; } else { return this.#encoder({ body, headers }); } From c43d01f473f3df46d3c718b61ddfa7892b5283c2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 08:16:01 +0000 Subject: [PATCH 09/33] chore(internal): remove mock server code --- scripts/mock | 41 ----------------------------------------- scripts/test | 46 ---------------------------------------------- 2 files changed, 87 deletions(-) delete mode 100755 scripts/mock diff --git a/scripts/mock b/scripts/mock deleted file mode 100755 index 0b28f6e..0000000 --- a/scripts/mock +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "$(dirname "$0")/.." - -if [[ -n "$1" && "$1" != '--'* ]]; then - URL="$1" - shift -else - URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" -fi - -# Check if the URL is empty -if [ -z "$URL" ]; then - echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" - exit 1 -fi - -echo "==> Starting mock server with URL ${URL}" - -# Run prism mock on the given spec -if [ "$1" == "--daemon" ]; then - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & - - # Wait for server to come online - echo -n "Waiting for server" - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do - echo -n "." - sleep 0.1 - done - - if grep -q "✖ fatal" ".prism.log"; then - cat .prism.log - exit 1 - fi - - echo -else - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" -fi diff --git a/scripts/test b/scripts/test index 7bce051..548da9b 100755 --- a/scripts/test +++ b/scripts/test @@ -4,53 +4,7 @@ set -e cd "$(dirname "$0")/.." -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -NC='\033[0m' # No Color -function prism_is_running() { - curl --silent "http://localhost:4010" >/dev/null 2>&1 -} - -kill_server_on_port() { - pids=$(lsof -t -i tcp:"$1" || echo "") - if [ "$pids" != "" ]; then - kill "$pids" - echo "Stopped $pids." - fi -} - -function is_overriding_api_base_url() { - [ -n "$TEST_API_BASE_URL" ] -} - -if ! is_overriding_api_base_url && ! prism_is_running ; then - # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT - - # Start the dev server - ./scripts/mock --daemon -fi - -if is_overriding_api_base_url ; then - echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" - echo -elif ! prism_is_running ; then - echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" - echo -e "running against your OpenAPI spec." - echo - echo -e "To run the server, pass in the path or url of your OpenAPI" - echo -e "spec to the prism command:" - echo - echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" - echo - - exit 1 -else - echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" - echo -fi echo "==> Running tests" ./node_modules/.bin/jest "$@" From ffdfd49ee108db6b215a92b7f7953041cef7ee67 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 08:16:58 +0000 Subject: [PATCH 10/33] chore: update mock server docs --- CONTRIBUTING.md | 6 ------ tests/api-resources/checkout-sessions.test.ts | 10 +++++----- tests/api-resources/customers.test.ts | 16 +++++++-------- tests/api-resources/discounts.test.ts | 14 ++++++------- .../api-resources/invoice-line-items.test.ts | 6 +++--- tests/api-resources/invoices.test.ts | 6 +++--- tests/api-resources/payment-methods.test.ts | 6 +++--- tests/api-resources/payments.test.ts | 8 ++++---- tests/api-resources/prices.test.ts | 12 +++++------ tests/api-resources/pricing-models.test.ts | 20 +++++++++---------- tests/api-resources/products.test.ts | 14 ++++++------- tests/api-resources/resource-claims.test.ts | 16 +++++++-------- tests/api-resources/resources.test.ts | 14 ++++++------- tests/api-resources/subscriptions.test.ts | 18 ++++++++--------- tests/api-resources/usage-events.test.ts | 6 +++--- tests/api-resources/usage-meters.test.ts | 14 ++++++------- 16 files changed, 90 insertions(+), 96 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9056f2..36fc118 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,12 +65,6 @@ $ pnpm link -—global @flowglad/node ## Running tests -Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. - -```sh -$ npx prism mock path/to/your/openapi.yml -``` - ```sh $ yarn run test ``` diff --git a/tests/api-resources/checkout-sessions.test.ts b/tests/api-resources/checkout-sessions.test.ts index 243549f..34a71f9 100644 --- a/tests/api-resources/checkout-sessions.test.ts +++ b/tests/api-resources/checkout-sessions.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource checkoutSessions', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.checkoutSessions.create({ checkoutSession: { @@ -27,7 +27,7 @@ describe('resource checkoutSessions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.checkoutSessions.create({ checkoutSession: { @@ -45,7 +45,7 @@ describe('resource checkoutSessions', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.checkoutSessions.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -57,7 +57,7 @@ describe('resource checkoutSessions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.checkoutSessions.list(); const rawResponse = await responsePromise.asResponse(); @@ -69,7 +69,7 @@ describe('resource checkoutSessions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/customers.test.ts b/tests/api-resources/customers.test.ts index 37d5654..4bec5d2 100644 --- a/tests/api-resources/customers.test.ts +++ b/tests/api-resources/customers.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource customers', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.customers.create({ customer: { @@ -26,7 +26,7 @@ describe('resource customers', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.customers.create({ customer: { @@ -42,7 +42,7 @@ describe('resource customers', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.customers.retrieve('externalId'); const rawResponse = await responsePromise.asResponse(); @@ -54,7 +54,7 @@ describe('resource customers', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.customers.update('externalId', { customer: {} }); const rawResponse = await responsePromise.asResponse(); @@ -66,7 +66,7 @@ describe('resource customers', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.customers.update('externalId', { customer: { @@ -81,7 +81,7 @@ describe('resource customers', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.customers.list(); const rawResponse = await responsePromise.asResponse(); @@ -93,7 +93,7 @@ describe('resource customers', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( @@ -101,7 +101,7 @@ describe('resource customers', () => { ).rejects.toThrow(Flowglad.NotFoundError); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieveBilling', async () => { const responsePromise = client.customers.retrieveBilling('externalId'); const rawResponse = await responsePromise.asResponse(); diff --git a/tests/api-resources/discounts.test.ts b/tests/api-resources/discounts.test.ts index c82904a..279285a 100644 --- a/tests/api-resources/discounts.test.ts +++ b/tests/api-resources/discounts.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource discounts', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.discounts.create({ discount: { @@ -28,7 +28,7 @@ describe('resource discounts', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.discounts.create({ discount: { @@ -44,7 +44,7 @@ describe('resource discounts', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.discounts.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -56,7 +56,7 @@ describe('resource discounts', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.discounts.update('id', { discount: { @@ -76,7 +76,7 @@ describe('resource discounts', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.discounts.update('id', { discount: { @@ -92,7 +92,7 @@ describe('resource discounts', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.discounts.list(); const rawResponse = await responsePromise.asResponse(); @@ -104,7 +104,7 @@ describe('resource discounts', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/invoice-line-items.test.ts b/tests/api-resources/invoice-line-items.test.ts index 761f6b8..af01fe3 100644 --- a/tests/api-resources/invoice-line-items.test.ts +++ b/tests/api-resources/invoice-line-items.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource invoiceLineItems', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.invoiceLineItems.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource invoiceLineItems', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.invoiceLineItems.list(); const rawResponse = await responsePromise.asResponse(); @@ -32,7 +32,7 @@ describe('resource invoiceLineItems', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/invoices.test.ts b/tests/api-resources/invoices.test.ts index deecc0f..389bd91 100644 --- a/tests/api-resources/invoices.test.ts +++ b/tests/api-resources/invoices.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource invoices', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.invoices.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource invoices', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.invoices.list(); const rawResponse = await responsePromise.asResponse(); @@ -32,7 +32,7 @@ describe('resource invoices', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/payment-methods.test.ts b/tests/api-resources/payment-methods.test.ts index 9afdb4c..11cbb8a 100644 --- a/tests/api-resources/payment-methods.test.ts +++ b/tests/api-resources/payment-methods.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource paymentMethods', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.paymentMethods.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource paymentMethods', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.paymentMethods.list(); const rawResponse = await responsePromise.asResponse(); @@ -32,7 +32,7 @@ describe('resource paymentMethods', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/payments.test.ts b/tests/api-resources/payments.test.ts index 48de50f..20843ee 100644 --- a/tests/api-resources/payments.test.ts +++ b/tests/api-resources/payments.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource payments', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.payments.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource payments', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.payments.list(); const rawResponse = await responsePromise.asResponse(); @@ -32,7 +32,7 @@ describe('resource payments', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( @@ -40,7 +40,7 @@ describe('resource payments', () => { ).rejects.toThrow(Flowglad.NotFoundError); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('refund', async () => { const responsePromise = client.payments.refund('id', {}); const rawResponse = await responsePromise.asResponse(); diff --git a/tests/api-resources/prices.test.ts b/tests/api-resources/prices.test.ts index ba6e830..3a40621 100644 --- a/tests/api-resources/prices.test.ts +++ b/tests/api-resources/prices.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource prices', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.prices.create({ price: { @@ -29,7 +29,7 @@ describe('resource prices', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.prices.create({ price: { @@ -49,7 +49,7 @@ describe('resource prices', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.prices.update('id', { price: { @@ -67,7 +67,7 @@ describe('resource prices', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.prices.update('id', { price: { @@ -81,7 +81,7 @@ describe('resource prices', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.prices.list(); const rawResponse = await responsePromise.asResponse(); @@ -93,7 +93,7 @@ describe('resource prices', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/pricing-models.test.ts b/tests/api-resources/pricing-models.test.ts index 91bb55f..f879e00 100644 --- a/tests/api-resources/pricing-models.test.ts +++ b/tests/api-resources/pricing-models.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource pricingModels', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.pricingModels.create({ pricingModel: { name: 'x' } }); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource pricingModels', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.pricingModels.create({ pricingModel: { name: 'x', isDefault: true }, @@ -28,7 +28,7 @@ describe('resource pricingModels', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.pricingModels.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -40,7 +40,7 @@ describe('resource pricingModels', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.pricingModels.update('id', { pricingModel: { id: 'id' } }); const rawResponse = await responsePromise.asResponse(); @@ -52,7 +52,7 @@ describe('resource pricingModels', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.pricingModels.update('id', { pricingModel: { @@ -63,7 +63,7 @@ describe('resource pricingModels', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.pricingModels.list(); const rawResponse = await responsePromise.asResponse(); @@ -75,7 +75,7 @@ describe('resource pricingModels', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( @@ -83,7 +83,7 @@ describe('resource pricingModels', () => { ).rejects.toThrow(Flowglad.NotFoundError); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('clone: only required params', async () => { const responsePromise = client.pricingModels.clone('id', { name: 'name' }); const rawResponse = await responsePromise.asResponse(); @@ -95,7 +95,7 @@ describe('resource pricingModels', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('clone: required and optional params', async () => { const response = await client.pricingModels.clone('id', { name: 'name', @@ -103,7 +103,7 @@ describe('resource pricingModels', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieveDefault', async () => { const responsePromise = client.pricingModels.retrieveDefault(); const rawResponse = await responsePromise.asResponse(); diff --git a/tests/api-resources/products.test.ts b/tests/api-resources/products.test.ts index 5cd9d87..31a2d94 100644 --- a/tests/api-resources/products.test.ts +++ b/tests/api-resources/products.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource products', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.products.create({ price: { @@ -33,7 +33,7 @@ describe('resource products', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.products.create({ price: { @@ -64,7 +64,7 @@ describe('resource products', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.products.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -76,7 +76,7 @@ describe('resource products', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.products.update('id', { product: { @@ -94,7 +94,7 @@ describe('resource products', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.products.update('id', { product: { @@ -126,7 +126,7 @@ describe('resource products', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.products.list(); const rawResponse = await responsePromise.asResponse(); @@ -138,7 +138,7 @@ describe('resource products', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( diff --git a/tests/api-resources/resource-claims.test.ts b/tests/api-resources/resource-claims.test.ts index 7335150..eff5420 100644 --- a/tests/api-resources/resource-claims.test.ts +++ b/tests/api-resources/resource-claims.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource resourceClaims', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('claim: only required params', async () => { const responsePromise = client.resourceClaims.claim('subscriptionId', { resourceSlug: 'resourceSlug' }); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource resourceClaims', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('claim: required and optional params', async () => { const response = await client.resourceClaims.claim('subscriptionId', { resourceSlug: 'resourceSlug', @@ -31,7 +31,7 @@ describe('resource resourceClaims', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('listUsages', async () => { const responsePromise = client.resourceClaims.listUsages('subscriptionId'); const rawResponse = await responsePromise.asResponse(); @@ -43,7 +43,7 @@ describe('resource resourceClaims', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('listUsages: 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( @@ -55,7 +55,7 @@ describe('resource resourceClaims', () => { ).rejects.toThrow(Flowglad.NotFoundError); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('release: only required params', async () => { const responsePromise = client.resourceClaims.release('subscriptionId', { resourceSlug: 'resourceSlug' }); const rawResponse = await responsePromise.asResponse(); @@ -67,7 +67,7 @@ describe('resource resourceClaims', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('release: required and optional params', async () => { const response = await client.resourceClaims.release('subscriptionId', { resourceSlug: 'resourceSlug', @@ -78,7 +78,7 @@ describe('resource resourceClaims', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieveUsage', async () => { const responsePromise = client.resourceClaims.retrieveUsage('subscriptionId'); const rawResponse = await responsePromise.asResponse(); @@ -90,7 +90,7 @@ describe('resource resourceClaims', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieveUsage: 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( diff --git a/tests/api-resources/resources.test.ts b/tests/api-resources/resources.test.ts index 0610a11..9c121d0 100644 --- a/tests/api-resources/resources.test.ts +++ b/tests/api-resources/resources.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource resources', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.resources.create({ resource: { @@ -26,7 +26,7 @@ describe('resource resources', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.resources.create({ resource: { @@ -38,7 +38,7 @@ describe('resource resources', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.resources.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -50,7 +50,7 @@ describe('resource resources', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.resources.update('id', { resource: { id: 'id' } }); const rawResponse = await responsePromise.asResponse(); @@ -62,7 +62,7 @@ describe('resource resources', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.resources.update('id', { resource: { @@ -74,7 +74,7 @@ describe('resource resources', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list: only required params', async () => { const responsePromise = client.resources.list({ pricingModelId: 'pricingModelId' }); const rawResponse = await responsePromise.asResponse(); @@ -86,7 +86,7 @@ describe('resource resources', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list: required and optional params', async () => { const response = await client.resources.list({ pricingModelId: 'pricingModelId' }); }); diff --git a/tests/api-resources/subscriptions.test.ts b/tests/api-resources/subscriptions.test.ts index d540161..f819793 100644 --- a/tests/api-resources/subscriptions.test.ts +++ b/tests/api-resources/subscriptions.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource subscriptions', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create', async () => { const responsePromise = client.subscriptions.create({}); const rawResponse = await responsePromise.asResponse(); @@ -20,7 +20,7 @@ describe('resource subscriptions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.subscriptions.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -32,7 +32,7 @@ describe('resource subscriptions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.subscriptions.list(); const rawResponse = await responsePromise.asResponse(); @@ -44,7 +44,7 @@ describe('resource subscriptions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( @@ -52,7 +52,7 @@ describe('resource subscriptions', () => { ).rejects.toThrow(Flowglad.NotFoundError); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('adjust: only required params', async () => { const responsePromise = client.subscriptions.adjust('id', { adjustment: { @@ -77,7 +77,7 @@ describe('resource subscriptions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('adjust: required and optional params', async () => { const response = await client.subscriptions.adjust('id', { adjustment: { @@ -102,7 +102,7 @@ describe('resource subscriptions', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('cancel: only required params', async () => { const responsePromise = client.subscriptions.cancel('id', { cancellation: { timing: 'at_end_of_current_billing_period' }, @@ -116,14 +116,14 @@ describe('resource subscriptions', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('cancel: required and optional params', async () => { const response = await client.subscriptions.cancel('id', { cancellation: { timing: 'at_end_of_current_billing_period' }, }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('uncancel', async () => { const responsePromise = client.subscriptions.uncancel('id'); const rawResponse = await responsePromise.asResponse(); diff --git a/tests/api-resources/usage-events.test.ts b/tests/api-resources/usage-events.test.ts index 9187657..d90e1fc 100644 --- a/tests/api-resources/usage-events.test.ts +++ b/tests/api-resources/usage-events.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource usageEvents', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.usageEvents.create({ usageEvent: { @@ -26,7 +26,7 @@ describe('resource usageEvents', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.usageEvents.create({ usageEvent: { @@ -43,7 +43,7 @@ describe('resource usageEvents', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.usageEvents.retrieve('id'); const rawResponse = await responsePromise.asResponse(); diff --git a/tests/api-resources/usage-meters.test.ts b/tests/api-resources/usage-meters.test.ts index 9c4211d..024eb07 100644 --- a/tests/api-resources/usage-meters.test.ts +++ b/tests/api-resources/usage-meters.test.ts @@ -8,7 +8,7 @@ const client = new Flowglad({ }); describe('resource usageMeters', () => { - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: only required params', async () => { const responsePromise = client.usageMeters.create({ usageMeter: { @@ -26,7 +26,7 @@ describe('resource usageMeters', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('create: required and optional params', async () => { const response = await client.usageMeters.create({ usageMeter: { @@ -43,7 +43,7 @@ describe('resource usageMeters', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('retrieve', async () => { const responsePromise = client.usageMeters.retrieve('id'); const rawResponse = await responsePromise.asResponse(); @@ -55,7 +55,7 @@ describe('resource usageMeters', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: only required params', async () => { const responsePromise = client.usageMeters.update('id', { usageMeter: { id: 'id' } }); const rawResponse = await responsePromise.asResponse(); @@ -67,7 +67,7 @@ describe('resource usageMeters', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('update: required and optional params', async () => { const response = await client.usageMeters.update('id', { usageMeter: { @@ -79,7 +79,7 @@ describe('resource usageMeters', () => { }); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('list', async () => { const responsePromise = client.usageMeters.list(); const rawResponse = await responsePromise.asResponse(); @@ -91,7 +91,7 @@ describe('resource usageMeters', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // Prism tests are disabled + // Mock server tests are disabled test.skip('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( From be11d0a5c085b7c83925d729adda0c419195e9de Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 08:37:38 +0000 Subject: [PATCH 11/33] fix(docs/contributing): correct pnpm link command --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36fc118..a080498 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,7 @@ $ yarn link @flowglad/node # With pnpm $ pnpm link --global $ cd ../my-package -$ pnpm link -—global @flowglad/node +$ pnpm link --global @flowglad/node ``` ## Running tests From 3792b09d9a46f121bd4d45e1b7142170ce039c3d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 09:25:53 +0000 Subject: [PATCH 12/33] chore(internal): move stringifyQuery implementation to internal function --- src/client.ts | 10 +++++----- src/internal/utils.ts | 1 + src/internal/utils/query.ts | 7 +++++++ tests/stringifyQuery.test.ts | 6 ++---- 4 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 src/internal/utils/query.ts diff --git a/src/client.ts b/src/client.ts index 7402a0b..d5b6f09 100644 --- a/src/client.ts +++ b/src/client.ts @@ -11,7 +11,7 @@ import type { APIResponseProps } from './internal/parse'; import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; import * as Opts from './internal/request-options'; -import * as qs from './internal/qs'; +import { stringifyQuery } from './internal/utils/query'; import { VERSION } from './version'; import * as Errors from './core/error'; import * as Uploads from './core/uploads'; @@ -365,8 +365,8 @@ export class Flowglad { return buildHeaders([{ Authorization: this.apiKey }]); } - protected stringifyQuery(query: Record): string { - return qs.stringify(query, { arrayFormat: 'comma' }); + protected stringifyQuery(query: object | Record): string { + return stringifyQuery(query); } private getUserAgent(): string { @@ -403,7 +403,7 @@ export class Flowglad { } if (typeof query === 'object' && query && !Array.isArray(query)) { - url.search = this.stringifyQuery(query as Record); + url.search = this.stringifyQuery(query); } return url.toString(); @@ -842,7 +842,7 @@ export class Flowglad { ) { return { bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' }, - body: this.stringifyQuery(body as Record), + body: this.stringifyQuery(body), }; } else { return this.#encoder({ body, headers }); diff --git a/src/internal/utils.ts b/src/internal/utils.ts index 3cbfacc..c591353 100644 --- a/src/internal/utils.ts +++ b/src/internal/utils.ts @@ -6,3 +6,4 @@ export * from './utils/env'; export * from './utils/log'; export * from './utils/uuid'; export * from './utils/sleep'; +export * from './utils/query'; diff --git a/src/internal/utils/query.ts b/src/internal/utils/query.ts new file mode 100644 index 0000000..0139cac --- /dev/null +++ b/src/internal/utils/query.ts @@ -0,0 +1,7 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import * as qs from '../qs/stringify'; + +export function stringifyQuery(query: object | Record) { + return qs.stringify(query, { arrayFormat: 'comma' }); +} diff --git a/tests/stringifyQuery.test.ts b/tests/stringifyQuery.test.ts index c875a11..00aabbd 100644 --- a/tests/stringifyQuery.test.ts +++ b/tests/stringifyQuery.test.ts @@ -1,8 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { Flowglad } from '@flowglad/node'; - -const { stringifyQuery } = Flowglad.prototype as any; +import { stringifyQuery } from '@flowglad/node/internal/utils/query'; describe(stringifyQuery, () => { for (const [input, expected] of [ @@ -15,7 +13,7 @@ describe(stringifyQuery, () => { 'e=f', )}=${encodeURIComponent('g&h')}`, ], - ]) { + ] as const) { it(`${JSON.stringify(input)} -> ${expected}`, () => { expect(stringifyQuery(input)).toEqual(expected); }); From 1fa19be68f6a9fa3fb441055d9e7cbfea2d75de5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:41:25 +0000 Subject: [PATCH 13/33] chore(internal): codegen related update --- src/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.ts b/src/client.ts index d5b6f09..3eda714 100644 --- a/src/client.ts +++ b/src/client.ts @@ -708,9 +708,9 @@ export class Flowglad { } } - // If the API asks us to wait a certain amount of time (and it's a reasonable amount), - // just do what it says, but otherwise calculate a default - if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) { + // If the API asks us to wait a certain amount of time, just do what it + // says, but otherwise calculate a default + if (timeoutMillis === undefined) { const maxRetries = options.maxRetries ?? this.maxRetries; timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries); } From 2e885d3664f770c40e2e2ad106791a9108a7a26b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 19:42:14 +0000 Subject: [PATCH 14/33] chore(ci): skip uploading artifacts on stainless-internal branches --- .github/workflows/ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66ef3d6..f4da103 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,14 +55,18 @@ jobs: run: ./scripts/build - name: Get GitHub OIDC Token - if: github.repository == 'stainless-sdks/flowglad-typescript' + if: |- + github.repository == 'stainless-sdks/flowglad-typescript' && + !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); - name: Upload tarball - if: github.repository == 'stainless-sdks/flowglad-typescript' + if: |- + github.repository == 'stainless-sdks/flowglad-typescript' && + !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s AUTH: ${{ steps.github-oidc.outputs.github_token }} From 2e95c3400584f0b269b3d03bf32baf5c9845ac0d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 19:50:30 +0000 Subject: [PATCH 15/33] fix(client): preserve URL params already embedded in path --- src/client.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 3eda714..5b36954 100644 --- a/src/client.ts +++ b/src/client.ts @@ -398,8 +398,9 @@ export class Flowglad { : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path)); const defaultQuery = this.defaultQuery(); - if (!isEmptyObj(defaultQuery)) { - query = { ...defaultQuery, ...query }; + const pathQuery = Object.fromEntries(url.searchParams); + if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) { + query = { ...pathQuery, ...defaultQuery, ...query }; } if (typeof query === 'object' && query && !Array.isArray(query)) { From a5c0a5203845a06b1ea7e42e9b20ac43c3a56c6c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 05:33:43 +0000 Subject: [PATCH 16/33] chore(internal): update dependencies to address dependabot vulnerabilities --- package.json | 11 +++++++++++ yarn.lock | 39 ++++++--------------------------------- 2 files changed, 17 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 93fd708..34e24f5 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,17 @@ "typescript": "5.8.3", "typescript-eslint": "8.31.1" }, + "overrides": { + "minimatch": "^9.0.5" + }, + "pnpm": { + "overrides": { + "minimatch": "^9.0.5" + } + }, + "resolutions": { + "minimatch": "^9.0.5" + }, "exports": { ".": { "import": "./dist/index.mjs", diff --git a/yarn.lock b/yarn.lock index fc9f262..078f09a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1219,15 +1219,7 @@ baseline-browser-mapping@^2.9.0: resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz#3b6af0bc032445bca04de58caa9a87cfe921cbb3" integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== -brace-expansion@^1.1.7: - version "1.1.12" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" - integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: +brace-expansion@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== @@ -1395,11 +1387,6 @@ commander@^10.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - convert-source-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" @@ -2600,26 +2587,12 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@^5.0.1, minimatch@^9.0.4, minimatch@^9.0.5: + version "9.0.9" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.9.tgz#9b0cb9fcb78087f6fd7eababe2511c4d3d60574e" + integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^2.0.2" minimist@^1.2.6: version "1.2.6" From f6b03e1a88298b87982b912bff58aee377bcd3cc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 12:32:47 +0000 Subject: [PATCH 17/33] chore(internal): tweak CI branches --- .github/workflows/ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4da103..e9e0bf0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,14 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'stl-preview-head/**' - - 'stl-preview-base/**' + branches: + - '**' + - '!integrated/**' + - '!stl-preview-head/**' + - '!stl-preview-base/**' + - '!generated' + - '!codegen/**' + - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' From b586d6c260bf9c09d0b9077092a6478e4e25e038 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 04:54:41 +0000 Subject: [PATCH 18/33] chore(internal): update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2412bb7..c85fe68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log node_modules yarn-error.log codegen.log From 535a81c7223a2b25aef440e1d7aa16bd8be2bbe9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 03:22:38 +0000 Subject: [PATCH 19/33] chore(ci): skip lint on metadata-only changes Note that we still want to run tests, as these depend on the metadata. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9e0bf0..b8827fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: timeout-minutes: 10 name: lint runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 @@ -38,7 +38,7 @@ jobs: timeout-minutes: 5 name: build runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') permissions: contents: read id-token: write From ad2acffa62f31f17960868ae3aeab9cb52139552 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 07:02:19 +0000 Subject: [PATCH 20/33] chore(internal): codegen related update --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 078f09a..e5e2a93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,9 +1220,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" - integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + version "2.0.3" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.3.tgz#0493338bdd58e319b1039c67cf7ee439892c01d9" + integrity sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA== dependencies: balanced-match "^1.0.0" From 4d3051b8e49e6df7c2f37ef00f5734dab256bf3d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:19:01 +0000 Subject: [PATCH 21/33] chore(internal): codegen related update --- src/internal/utils/env.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/utils/env.ts b/src/internal/utils/env.ts index 2d84800..cc5fa0f 100644 --- a/src/internal/utils/env.ts +++ b/src/internal/utils/env.ts @@ -9,10 +9,10 @@ */ export const readEnv = (env: string): string | undefined => { if (typeof (globalThis as any).process !== 'undefined') { - return (globalThis as any).process.env?.[env]?.trim() ?? undefined; + return (globalThis as any).process.env?.[env]?.trim() || undefined; } if (typeof (globalThis as any).Deno !== 'undefined') { - return (globalThis as any).Deno.env?.get?.(env)?.trim(); + return (globalThis as any).Deno.env?.get?.(env)?.trim() || undefined; } return undefined; }; From d8899f9ab15a0a6900be9342ed65916ea4a92fc2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 02:24:00 +0000 Subject: [PATCH 22/33] chore(internal): codegen related update --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e5e2a93..f6eae3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,9 +1220,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.3.tgz#0493338bdd58e319b1039c67cf7ee439892c01d9" - integrity sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.0.tgz#4f41a41190216ee36067ec381526fe9539c4f0ae" + integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w== dependencies: balanced-match "^1.0.0" From a5910a66a047c6dc6b067fb5a7a8310eacabdf87 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 03:59:09 +0000 Subject: [PATCH 23/33] chore(internal): more robust bootstrap script --- scripts/bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bootstrap b/scripts/bootstrap index a8b69ff..2e315f5 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response From be7a426b5810fd9d183b005f097175c8b230d5a6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 04:08:00 +0000 Subject: [PATCH 24/33] chore(internal): codegen related update --- scripts/utils/postprocess-files.cjs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs index deae575..a8cdeb7 100644 --- a/scripts/utils/postprocess-files.cjs +++ b/scripts/utils/postprocess-files.cjs @@ -23,12 +23,19 @@ async function postprocess() { // strip out lib="dom", types="node", and types="react" references; these // are needed at build time, but would pollute the user's TS environment - const transformed = code.replace( + let transformed = code.replace( /^ *\/\/\/ * ' '.repeat(match.length - 1) + '\n', ); + // TypeScript's declaration emitter collapses /** @ts-ignore */ onto the same + // line as the type declaration, which doesn't work. So we convert to // @ts-ignore + // on its own line to properly suppresses errors. + if (file.endsWith('.d.ts') || file.endsWith('.d.mts') || file.endsWith('.d.cts')) { + transformed = transformed.replace(/\/\*\* @ts-ignore\b[^*]*\*\/ /gm, '// @ts-ignore\n'); + } + if (transformed !== code) { console.error(`wrote ${path.relative(process.cwd(), file)}`); await fs.promises.writeFile(file, transformed, 'utf8'); From f11a428c27039ecfe3c3463c7503e6ecd4412dce Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 04:08:50 +0000 Subject: [PATCH 25/33] feat: support setting headers via env --- src/client.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/client.ts b/src/client.ts index 5b36954..0595359 100644 --- a/src/client.ts +++ b/src/client.ts @@ -322,6 +322,18 @@ export class Flowglad { this.fetch = options.fetch ?? Shims.getDefaultFetch(); this.#encoder = Opts.FallbackEncoder; + const customHeadersEnv = readEnv('FLOWGLAD_CUSTOM_HEADERS'); + if (customHeadersEnv) { + const parsed: Record = {}; + for (const line of customHeadersEnv.split('\n')) { + const colon = line.indexOf(':'); + if (colon >= 0) { + parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim(); + } + } + options.defaultHeaders = { ...parsed, ...options.defaultHeaders }; + } + this._options = options; this.apiKey = apiKey; From 5fd099eb41153efbbeb5b15242afea4d9ea40221 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:47:06 +0000 Subject: [PATCH 26/33] chore(format): run eslint and prettier separately --- .github/workflows/release-doctor.yml | 1 - eslint.config.mjs | 3 --- package.json | 1 - scripts/fast-format | 9 +++----- scripts/format | 3 +-- scripts/lint | 3 +++ src/internal/types.ts | 14 ++++++------ yarn.lock | 32 ---------------------------- 8 files changed, 13 insertions(+), 53 deletions(-) diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index b4d7503..de830e5 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -19,4 +19,3 @@ jobs: bash ./bin/check-release-environment env: NPM_TOKEN: ${{ secrets.FLOWGLAD_NPM_TOKEN || secrets.NPM_TOKEN }} - diff --git a/eslint.config.mjs b/eslint.config.mjs index 1708505..6c461d8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,7 +1,6 @@ // @ts-check import tseslint from 'typescript-eslint'; import unusedImports from 'eslint-plugin-unused-imports'; -import prettier from 'eslint-plugin-prettier'; export default tseslint.config( { @@ -14,11 +13,9 @@ export default tseslint.config( plugins: { '@typescript-eslint': tseslint.plugin, 'unused-imports': unusedImports, - prettier, }, rules: { 'no-unused-vars': 'off', - 'prettier/prettier': 'error', 'unused-imports/no-unused-imports': 'error', 'no-restricted-imports': [ 'error', diff --git a/package.json b/package.json index 34e24f5..ee133d5 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/parser": "8.31.1", "eslint": "^9.39.1", - "eslint-plugin-prettier": "^5.4.1", "eslint-plugin-unused-imports": "^4.1.4", "iconv-lite": "^0.6.3", "jest": "^29.4.0", diff --git a/scripts/fast-format b/scripts/fast-format index 53721ac..f1873ae 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -31,10 +31,7 @@ if ! [ -z "$ESLINT_FILES" ]; then fi echo "==> Running prettier --write" -# format things eslint didn't -PRETTIER_FILES="$(grep '\.\(js\|json\)$' "$FILE_LIST" || true)" -if ! [ -z "$PRETTIER_FILES" ]; then - echo "$PRETTIER_FILES" | xargs ./node_modules/.bin/prettier \ - --write --cache --cache-strategy metadata --no-error-on-unmatched-pattern \ - '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs' +if ! [ -z "$FILE_LIST" ]; then + cat "$FILE_LIST" | xargs ./node_modules/.bin/prettier \ + --write --cache --cache-strategy metadata --no-error-on-unmatched-pattern --ignore-unknown fi diff --git a/scripts/format b/scripts/format index 7a75640..b1b2c17 100755 --- a/scripts/format +++ b/scripts/format @@ -8,5 +8,4 @@ echo "==> Running eslint --fix" ./node_modules/.bin/eslint --fix . echo "==> Running prettier --write" -# format things eslint didn't -./node_modules/.bin/prettier --write --cache --cache-strategy metadata . '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs' +./node_modules/.bin/prettier --write --cache --cache-strategy metadata . diff --git a/scripts/lint b/scripts/lint index 3ffb78a..1f53254 100755 --- a/scripts/lint +++ b/scripts/lint @@ -4,6 +4,9 @@ set -e cd "$(dirname "$0")/.." +echo "==> Running prettier --check" +./node_modules/.bin/prettier --check . + echo "==> Running eslint" ./node_modules/.bin/eslint . diff --git a/src/internal/types.ts b/src/internal/types.ts index b668dfc..a050513 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -40,7 +40,6 @@ type OverloadedParameters = : T extends (...args: infer A) => unknown ? A : never; -/* eslint-disable */ /** * These imports attempt to get types from a parent package's dependencies. * Unresolved bare specifiers can trigger [automatic type acquisition][1] in some projects, which @@ -63,19 +62,18 @@ type OverloadedParameters = * * [1]: https://www.typescriptlang.org/tsconfig/#typeAcquisition */ -/** @ts-ignore For users with \@types/node */ +/** @ts-ignore For users with \@types/node */ /* prettier-ignore */ type UndiciTypesRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with undici */ +/** @ts-ignore For users with undici */ /* prettier-ignore */ type UndiciRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with \@types/bun */ +/** @ts-ignore For users with \@types/bun */ /* prettier-ignore */ type BunRequestInit = globalThis.FetchRequestInit; -/** @ts-ignore For users with node-fetch@2 */ +/** @ts-ignore For users with node-fetch@2 */ /* prettier-ignore */ type NodeFetch2RequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */ +/** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */ /* prettier-ignore */ type NodeFetch3RequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; -/** @ts-ignore For users who use Deno */ +/** @ts-ignore For users who use Deno */ /* prettier-ignore */ type FetchRequestInit = NonNullable[1]>; -/* eslint-enable */ type RequestInits = | NotAny diff --git a/yarn.lock b/yarn.lock index f6eae3c..18e7cbd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -709,11 +709,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@pkgr/core@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.4.tgz#d897170a2b0ba51f78a099edccd968f7b103387c" - integrity sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw== - "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -1515,14 +1510,6 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-plugin-prettier@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.1.tgz#99b55d7dd70047886b2222fdd853665f180b36af" - integrity sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.11.7" - eslint-plugin-unused-imports@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz#62ddc7446ccbf9aa7b6f1f0b00a980423cda2738" @@ -1674,11 +1661,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -2841,13 +2823,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - prettier@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.1.tgz#6ba9f23165d690b6cbdaa88cb0807278f7019848" @@ -3144,13 +3119,6 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.11.7: - version "0.11.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.8.tgz#b2aaae998a4ef47ded60773ad06e7cb821f55457" - integrity sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A== - dependencies: - "@pkgr/core" "^0.2.4" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" From 6173dd636b71dcee1b2b6deea5a993d3049e9fb1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 04:55:28 +0000 Subject: [PATCH 27/33] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index c548c50..a7c7904 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 54 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad%2Fflowglad-06c4dd78e137fdf8d3acd39424e5d6158e0a719903996d933af8832eee705d9c.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad/flowglad-06c4dd78e137fdf8d3acd39424e5d6158e0a719903996d933af8832eee705d9c.yml openapi_spec_hash: fd5d4fe4838681b6dc19595f6ad24923 config_hash: 7194205a326772d1af6151798bc4172e From 764f596cc20ce963d437f8d14a48e9c80c4a2ea7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 05:02:43 +0000 Subject: [PATCH 28/33] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index a7c7904..83562ea 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 54 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad/flowglad-06c4dd78e137fdf8d3acd39424e5d6158e0a719903996d933af8832eee705d9c.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/flowglad/flowglad-c0ecb31777a8b9fbe565a160dff198024134f09b2599cf1bbf4d0fc85f25168a.yml openapi_spec_hash: fd5d4fe4838681b6dc19595f6ad24923 config_hash: 7194205a326772d1af6151798bc4172e From 6420eb0370c498b66e6d9e1fb5aff4924a3629b5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 05:07:19 +0000 Subject: [PATCH 29/33] chore: redact api-key headers in debug logs --- src/internal/utils/log.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index eef9e76..a779457 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -107,6 +107,8 @@ export const formatRequestDetails = (details: { name, ( name.toLowerCase() === 'authorization' || + name.toLowerCase() === 'api-key' || + name.toLowerCase() === 'x-api-key' || name.toLowerCase() === 'cookie' || name.toLowerCase() === 'set-cookie' ) ? From fa199bbef026ba20d277ce81e0a928748a642e5e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 03:04:31 +0000 Subject: [PATCH 30/33] ci: pin GitHub Actions to commit SHAs Pin all GitHub Actions referenced in generated workflows (both first-party `actions/*` and third-party) to immutable commit SHAs. Updating pinned actions is now a deliberate codegen-side bump rather than implicit on every workflow run. --- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/publish-npm.yml | 4 ++-- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8827fc..803247b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,10 +21,10 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' @@ -43,10 +43,10 @@ jobs: contents: read id-token: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' @@ -61,7 +61,7 @@ jobs: github.repository == 'stainless-sdks/flowglad-typescript' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -80,10 +80,10 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 523aba4..f90fc8f 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1 with: node-version: '20' diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index de830e5..9b1d99b 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: 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@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | From aa9716df3bfa07a43ceccccc4a84400ee2960159 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 03:00:12 +0000 Subject: [PATCH 31/33] chore(tests): remove redundant File import --- tests/uploads.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 895db8b..27867e8 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,7 +1,6 @@ import fs from 'fs'; import type { ResponseLike } from '@flowglad/node/internal/to-file'; import { toFile } from '@flowglad/node/core/uploads'; -import { File } from 'node:buffer'; class MyClass { name: string = 'foo'; From ce0b41db297739443c68e79a149ed862b6bbb4ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 03:00:48 +0000 Subject: [PATCH 32/33] fix(typescript): upgrade tsc-multi so that it works with Node 26 --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index ee133d5..08e6328 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "publint": "^0.2.12", "ts-jest": "^29.1.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz", "tsconfig-paths": "^4.0.0", "tslib": "^2.8.1", "typescript": "5.8.3", diff --git a/yarn.lock b/yarn.lock index 18e7cbd..00842e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3192,9 +3192,9 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" -"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz": - version "1.1.9" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz": + version "1.1.11" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2" dependencies: debug "^4.3.7" fast-glob "^3.3.2" From 84ad0c55f552396eca6e3aa879eb4f464b5a3290 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 03:16:56 +0000 Subject: [PATCH 33/33] release: 0.30.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8316a6d..716d004 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.29.0" + ".": "0.30.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c6055d7..c065871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,48 @@ # Changelog +## 0.30.0 (2026-05-19) + +Full Changelog: [v0.29.0...v0.30.0](https://github.com/flowglad/flowglad-node/compare/v0.29.0...v0.30.0) + +### Features + +* support setting headers via env ([f11a428](https://github.com/flowglad/flowglad-node/commit/f11a428c27039ecfe3c3463c7503e6ecd4412dce)) + + +### Bug Fixes + +* **client:** avoid memory leak with abort signals ([56900be](https://github.com/flowglad/flowglad-node/commit/56900bed3729ab2a7f4d872fad1692a888cbf802)) +* **client:** avoid removing abort listener too early ([db6b522](https://github.com/flowglad/flowglad-node/commit/db6b522ba19e11051a8d26be9905d8a88796d455)) +* **client:** preserve URL params already embedded in path ([2e95c34](https://github.com/flowglad/flowglad-node/commit/2e95c3400584f0b269b3d03bf32baf5c9845ac0d)) +* **docs/contributing:** correct pnpm link command ([be11d0a](https://github.com/flowglad/flowglad-node/commit/be11d0a5c085b7c83925d729adda0c419195e9de)) +* **types:** correctly define false enum ([d98d3e7](https://github.com/flowglad/flowglad-node/commit/d98d3e7d87551397703c141d873e8b4234a8a889)) +* **typescript:** upgrade tsc-multi so that it works with Node 26 ([ce0b41d](https://github.com/flowglad/flowglad-node/commit/ce0b41db297739443c68e79a149ed862b6bbb4ef)) + + +### Chores + +* **ci:** skip lint on metadata-only changes ([535a81c](https://github.com/flowglad/flowglad-node/commit/535a81c7223a2b25aef440e1d7aa16bd8be2bbe9)) +* **ci:** skip uploading artifacts on stainless-internal branches ([2e885d3](https://github.com/flowglad/flowglad-node/commit/2e885d3664f770c40e2e2ad106791a9108a7a26b)) +* **ci:** upgrade `actions/github-script` ([ab1bfe8](https://github.com/flowglad/flowglad-node/commit/ab1bfe8705631f229c10ac023bc8ae205c4edd46)) +* **client:** do not parse responses with empty content-length ([fdf2834](https://github.com/flowglad/flowglad-node/commit/fdf283447a556e939343febecc89663c4b2ac9e6)) +* **client:** restructure abort controller binding ([55978f2](https://github.com/flowglad/flowglad-node/commit/55978f2f8d4ece515b0613b7e47833a5dd7c1a84)) +* **format:** run eslint and prettier separately ([5fd099e](https://github.com/flowglad/flowglad-node/commit/5fd099eb41153efbbeb5b15242afea4d9ea40221)) +* **internal/client:** fix form-urlencoded requests ([a7577d3](https://github.com/flowglad/flowglad-node/commit/a7577d3c4b321509d224b71464e184e8df875888)) +* **internal:** avoid type checking errors with ts-reset ([a460ca8](https://github.com/flowglad/flowglad-node/commit/a460ca893ece9bf09c768db7fd3122c5b60d7caa)) +* **internal:** codegen related update ([be7a426](https://github.com/flowglad/flowglad-node/commit/be7a426b5810fd9d183b005f097175c8b230d5a6)) +* **internal:** codegen related update ([d8899f9](https://github.com/flowglad/flowglad-node/commit/d8899f9ab15a0a6900be9342ed65916ea4a92fc2)) +* **internal:** codegen related update ([4d3051b](https://github.com/flowglad/flowglad-node/commit/4d3051b8e49e6df7c2f37ef00f5734dab256bf3d)) +* **internal:** codegen related update ([ad2acff](https://github.com/flowglad/flowglad-node/commit/ad2acffa62f31f17960868ae3aeab9cb52139552)) +* **internal:** codegen related update ([1fa19be](https://github.com/flowglad/flowglad-node/commit/1fa19be68f6a9fa3fb441055d9e7cbfea2d75de5)) +* **internal:** more robust bootstrap script ([a5910a6](https://github.com/flowglad/flowglad-node/commit/a5910a66a047c6dc6b067fb5a7a8310eacabdf87)) +* **internal:** move stringifyQuery implementation to internal function ([3792b09](https://github.com/flowglad/flowglad-node/commit/3792b09d9a46f121bd4d45e1b7142170ce039c3d)) +* **internal:** remove mock server code ([c43d01f](https://github.com/flowglad/flowglad-node/commit/c43d01f473f3df46d3c718b61ddfa7892b5283c2)) +* **internal:** tweak CI branches ([f6b03e1](https://github.com/flowglad/flowglad-node/commit/f6b03e1a88298b87982b912bff58aee377bcd3cc)) +* **internal:** update dependencies to address dependabot vulnerabilities ([a5c0a52](https://github.com/flowglad/flowglad-node/commit/a5c0a5203845a06b1ea7e42e9b20ac43c3a56c6c)) +* **internal:** update gitignore ([b586d6c](https://github.com/flowglad/flowglad-node/commit/b586d6c260bf9c09d0b9077092a6478e4e25e038)) +* redact api-key headers in debug logs ([6420eb0](https://github.com/flowglad/flowglad-node/commit/6420eb0370c498b66e6d9e1fb5aff4924a3629b5)) +* **tests:** remove redundant File import ([aa9716d](https://github.com/flowglad/flowglad-node/commit/aa9716df3bfa07a43ceccccc4a84400ee2960159)) +* update mock server docs ([ffdfd49](https://github.com/flowglad/flowglad-node/commit/ffdfd49ee108db6b215a92b7f7953041cef7ee67)) + ## 0.29.0 (2026-01-18) Full Changelog: [v0.28.0...v0.29.0](https://github.com/flowglad/flowglad-node/compare/v0.28.0...v0.29.0) diff --git a/package.json b/package.json index 08e6328..848fab6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@flowglad/node", - "version": "0.29.0", + "version": "0.30.0", "description": "The official TypeScript library for the Flowglad API", "author": "Flowglad ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index bef2b64..91a9bb6 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.29.0'; // x-release-please-version +export const VERSION = '0.30.0'; // x-release-please-version