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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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 94ece5603462a3ff45d3140fa6ca7dd58c40895e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 02:21:10 +0000 Subject: [PATCH 33/40] chore(internal): codegen related update --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 00842e3..06fc108 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1215,9 +1215,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.0.tgz#4f41a41190216ee36067ec381526fe9539c4f0ae" - integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w== + version "2.1.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.1.tgz#c68b1c4111c76aae3a6fba55d496cee10c39dad8" + integrity sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA== dependencies: balanced-match "^1.0.0" From 6c8003d99ba7bb1357b557e6c1618f29504456c9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 02:18:00 +0000 Subject: [PATCH 34/40] fix(client): send content-type header for requests with an omitted optional body --- src/client.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 0595359..86c9c3e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -817,11 +817,19 @@ export class Flowglad { return () => controller.abort(); } - private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): { + private buildBody({ options }: { options: FinalRequestOptions }): { bodyHeaders: HeadersLike; body: BodyInit | undefined; } { + const { body, headers: rawHeaders } = options; if (!body) { + // A resource method always passes a `body` key when its operation defines a + // request body, even if the caller omitted an optional body param. Keep the + // content-type for those, and only elide it for operations with no body at + // all (e.g. GET/DELETE). + if (body == null && 'body' in options) { + return this.#encoder({ body, headers: buildHeaders([rawHeaders]) }); + } return { bodyHeaders: undefined, body: undefined }; } const headers = buildHeaders([rawHeaders]); From aee370fd4d291e2c9082a3441fefb2f77dc7084e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2026 02:24:40 +0000 Subject: [PATCH 35/40] chore(internal): codegen related update --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 06fc108..38236e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1215,9 +1215,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.1.tgz#c68b1c4111c76aae3a6fba55d496cee10c39dad8" - integrity sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA== + version "2.1.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.2.tgz#0bba2271feb7d458b0d31ad13625aaa4754431e2" + integrity sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA== dependencies: balanced-match "^1.0.0" From 882bc36db35aa52b25df7d1000fee49660b57562 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2026 02:25:12 +0000 Subject: [PATCH 36/40] fix(ci): bump @arethetypeswrong/cli to ^0.18.0 and run CI workflows on Node 24 --- .github/workflows/ci.yml | 6 ++-- .github/workflows/publish-npm.yml | 2 +- package.json | 2 +- yarn.lock | 51 +++++++++++++++++++------------ 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 803247b..a9897fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: - name: Set up Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: '20' + node-version: '24' - name: Bootstrap run: ./scripts/bootstrap @@ -48,7 +48,7 @@ jobs: - name: Set up Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: '20' + node-version: '24' - name: Bootstrap run: ./scripts/bootstrap @@ -85,7 +85,7 @@ jobs: - name: Set up Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: '20' + node-version: '24' - name: Bootstrap run: ./scripts/bootstrap diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index f90fc8f..3f2ea25 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1 with: - node-version: '20' + node-version: '24' - name: Install dependencies run: | diff --git a/package.json b/package.json index 08e6328..77e7c71 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "dependencies": {}, "devDependencies": { - "@arethetypeswrong/cli": "^0.17.0", + "@arethetypeswrong/cli": "^0.18.0", "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29", "@types/jest": "^29.4.0", diff --git a/yarn.lock b/yarn.lock index 38236e6..443cc05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,12 +12,12 @@ resolved "https://registry.yarnpkg.com/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz#ba9494f85eb83017c5c855763969caf1d0adea00" integrity sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw== -"@arethetypeswrong/cli@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@arethetypeswrong/cli/-/cli-0.17.0.tgz#f97f10926b3f9f9eb5117550242d2e06c25cadac" - integrity sha512-xSMW7bfzVWpYw5JFgZqBXqr6PdR0/REmn3DkxCES5N0JTcB0CVgbIynJCvKBFmXaPc3hzmmTrb7+yPDRoOSZdA== +"@arethetypeswrong/cli@^0.18.0": + version "0.18.4" + resolved "https://registry.yarnpkg.com/@arethetypeswrong/cli/-/cli-0.18.4.tgz#c31f54f3b0d0e0f3256ab3edb6530beeb5e64b4b" + integrity sha512-kNWo6LTzGAuLYPpJ7Sgo63whSUeeSuKMlYx6IBgzs4ONEG807gW4hSSENvpeCHzO2H2wIzG5EFl0OKBbqGBAyA== dependencies: - "@arethetypeswrong/core" "0.17.0" + "@arethetypeswrong/core" "0.18.4" chalk "^4.1.2" cli-table3 "^0.6.3" commander "^10.0.1" @@ -25,15 +25,16 @@ marked-terminal "^7.1.0" semver "^7.5.4" -"@arethetypeswrong/core@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@arethetypeswrong/core/-/core-0.17.0.tgz#abb3b5f425056d37193644c2a2de4aecf866b76b" - integrity sha512-FHyhFizXNetigTVsIhqXKGYLpazPS5YNojEPpZEUcBPt9wVvoEbNIvG+hybuBR+pjlRcbyuqhukHZm1fr+bDgA== +"@arethetypeswrong/core@0.18.4": + version "0.18.4" + resolved "https://registry.yarnpkg.com/@arethetypeswrong/core/-/core-0.18.4.tgz#24edea3d651dea7d32bf6f1cc9ee9a00db39de49" + integrity sha512-M5F0ePyN6h2Z6XxRiyIPqjGbltotXLjR0CKA0uKspsDu0QmgTNYvRb4RSQPMUs2ZXZHCCYpbaZbFbYOXLxCjUA== dependencies: "@andrewbranch/untar.js" "^1.0.3" + "@loaderkit/resolve" "^1.0.2" cjs-module-lexer "^1.2.3" - fflate "^0.8.2" - lru-cache "^10.4.3" + fflate "^0.8.3" + lru-cache "^11.0.1" semver "^7.5.4" typescript "5.6.1-rc" validate-npm-package-name "^5.0.0" @@ -306,6 +307,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@braidai/lang@^1.0.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@braidai/lang/-/lang-1.1.2.tgz#65bc2bc1db6d00e153b95ac7006f4573e289e9be" + integrity sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -688,6 +694,13 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@loaderkit/resolve@^1.0.2": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@loaderkit/resolve/-/resolve-1.0.6.tgz#8d45341e688faecc25b3ae919c0f45d94c4e26c9" + integrity sha512-G8FdIoF5CypfwmD9rl8BXod5HDn8JqB0CCNBXDTaRZ+yRYhARrrSToX1zg1zy9jX3zLqigsELwhT4gNtkdQAUg== + dependencies: + "@braidai/lang" "^1.0.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1696,10 +1709,10 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -fflate@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" - integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== +fflate@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.3.tgz#bc27d8eb30343d4d512abb03480202ce65d825fc" + integrity sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA== file-entry-cache@^8.0.0: version "8.0.0" @@ -2490,10 +2503,10 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lru-cache@^10.4.3: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.1: + version "11.5.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.2.tgz#00e16665c90c620fba14a3c368732a976493f760" + integrity sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g== lru-cache@^5.1.1: version "5.1.1" From 28089081cbc8b0c2b7a18b110711d58c9c5ed861 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 18 Jul 2026 02:16:31 +0000 Subject: [PATCH 37/40] feat(stlc): configurable CI runner and private-production-repo support in workflow templates --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9897fa..e1bc66f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && '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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -37,7 +37,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && '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') permissions: contents: read @@ -77,7 +77,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ${{ github.repository == 'stainless-sdks/flowglad-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From f31919f1848bdd384d75b5b850119c5b03416c06 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 02:22:51 +0000 Subject: [PATCH 38/40] chore(internal): codegen related update --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 443cc05..957aa46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1228,9 +1228,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.2.tgz#0bba2271feb7d458b0d31ad13625aaa4754431e2" - integrity sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA== + version "2.1.3" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.3.tgz#1bf69aacdf6a4380ca17c284d9f928d4aa6401bc" + integrity sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A== dependencies: balanced-match "^1.0.0" From 3cc0a7c8157c5dfb7caf0a94d0d8b15cf7fb2b0c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 02:12:44 +0000 Subject: [PATCH 39/40] fix(stlc): stop hand-edited CI workflows from blocking seals and builds Editing the generated CI/release workflows in an SDK repo is supported: stlc writes them once and then leaves them under the repo's ownership. Two safety checks did not account for that and could refuse to seal custom code, or refuse to build, over workflow edits that were never at risk of being overwritten. The seal refusal could not be cleared by rebuilding. Sealing is also now recorded in place rather than under a new filename each time, so an interrupted build can no longer leave a workspace with no record of its sealed custom code, and sealing one branch no longer discards the record for another. --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 957aa46..f16b683 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1228,9 +1228,9 @@ baseline-browser-mapping@^2.9.0: integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg== brace-expansion@^2.0.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.3.tgz#1bf69aacdf6a4380ca17c284d9f928d4aa6401bc" - integrity sha512-DRdx5neNsG/QXbniLFWi2YmC/68oeOOmKz6zOjVk6ZS1ZLXgLIKqVEc6hWsmkjBbgii0SwaBTcJ5XKj5gzY/4A== + version "2.1.4" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.4.tgz#589dab11c0018d0366be64cd8bf12c8dbecc8326" + integrity sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg== dependencies: balanced-match "^1.0.0" From 806a1959bdd8fc90244843b46860a9cfd50b6fa0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 02:13:17 +0000 Subject: [PATCH 40/40] release: 0.30.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 54 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..6b12e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,55 @@ # Changelog +## 0.30.0 (2026-07-31) + +Full Changelog: [v0.29.0...v0.30.0](https://github.com/flowglad/flowglad-node/compare/v0.29.0...v0.30.0) + +### Features + +* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([2808908](https://github.com/flowglad/flowglad-node/commit/28089081cbc8b0c2b7a18b110711d58c9c5ed861)) +* support setting headers via env ([f11a428](https://github.com/flowglad/flowglad-node/commit/f11a428c27039ecfe3c3463c7503e6ecd4412dce)) + + +### Bug Fixes + +* **ci:** bump @arethetypeswrong/cli to ^0.18.0 and run CI workflows on Node 24 ([882bc36](https://github.com/flowglad/flowglad-node/commit/882bc36db35aa52b25df7d1000fee49660b57562)) +* **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)) +* **client:** send content-type header for requests with an omitted optional body ([6c8003d](https://github.com/flowglad/flowglad-node/commit/6c8003d99ba7bb1357b557e6c1618f29504456c9)) +* **docs/contributing:** correct pnpm link command ([be11d0a](https://github.com/flowglad/flowglad-node/commit/be11d0a5c085b7c83925d729adda0c419195e9de)) +* **stlc:** stop hand-edited CI workflows from blocking seals and builds ([3cc0a7c](https://github.com/flowglad/flowglad-node/commit/3cc0a7c8157c5dfb7caf0a94d0d8b15cf7fb2b0c)) +* **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 ([f31919f](https://github.com/flowglad/flowglad-node/commit/f31919f1848bdd384d75b5b850119c5b03416c06)) +* **internal:** codegen related update ([aee370f](https://github.com/flowglad/flowglad-node/commit/aee370fd4d291e2c9082a3441fefb2f77dc7084e)) +* **internal:** codegen related update ([94ece56](https://github.com/flowglad/flowglad-node/commit/94ece5603462a3ff45d3140fa6ca7dd58c40895e)) +* **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 77e7c71..2418643 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