From ea9f4ab77357b8deae9ee5836f797e30663d230f Mon Sep 17 00:00:00 2001 From: scalarbot Date: Fri, 28 Aug 2026 19:11:40 +0000 Subject: [PATCH 1/7] chore(api): update generated SDK content 1 generated file changed with no detected API surface change (documentation, examples, or file content). Build: KodwE3s93gklIPrtaSeZJ --- src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.ts b/src/version.ts index 7b9493e..72bdf2b 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ // File generated from our OpenAPI spec by Scalar. See README.md for details. -export const VERSION = '0.3.1'; // x-release-please-version +export const VERSION = '0.4.0'; // x-release-please-version From 91db268588ad2ec5fd3ab98b70cb5c0e0e290854 Mon Sep 17 00:00:00 2001 From: scalarbot Date: Fri, 28 Aug 2026 19:26:34 +0000 Subject: [PATCH 2/7] chore(api): update generated SDK content 1 generated file changed with no detected API surface change (documentation, examples, or file content). Build: SSUZ1KR5x7GqRYrSDfKlK --- src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.ts b/src/version.ts index 72bdf2b..091efaf 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ // File generated from our OpenAPI spec by Scalar. See README.md for details. -export const VERSION = '0.4.0'; // x-release-please-version +export const VERSION = '0.4.1'; // x-release-please-version From 14a33a0a635e5f79fe631d8d0719ed86ee315526 Mon Sep 17 00:00:00 2001 From: scalarbot Date: Tue, 1 Sep 2026 16:49:38 +0000 Subject: [PATCH 3/7] chore(api): regenerate SDK - Regenerated with generator `0.31.1` (previously `0.30.1`). Build: oEoH9Lxloq9EfBy11HQGV --- scalar-sdk.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scalar-sdk.manifest.json b/scalar-sdk.manifest.json index 8a6195f..3dfeb6e 100644 --- a/scalar-sdk.manifest.json +++ b/scalar-sdk.manifest.json @@ -1,7 +1,7 @@ { "name": "Scalar", "slug": "scalar", - "generatorVersion": "0.30.1", + "generatorVersion": "0.31.1", "servers": [ "https://access.scalar.com" ], From a12790a69a78c5cb72c7546414185fed9d706b15 Mon Sep 17 00:00:00 2001 From: scalarbot Date: Tue, 1 Sep 2026 22:12:07 +0000 Subject: [PATCH 4/7] chore(api): regenerate SDK - Regenerated with generator `0.32.0` (previously `0.31.1`). Build: NzOu2CK8x2XtBME8WOwD4 --- scalar-sdk.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scalar-sdk.manifest.json b/scalar-sdk.manifest.json index 3dfeb6e..e7baf96 100644 --- a/scalar-sdk.manifest.json +++ b/scalar-sdk.manifest.json @@ -1,7 +1,7 @@ { "name": "Scalar", "slug": "scalar", - "generatorVersion": "0.31.1", + "generatorVersion": "0.32.0", "servers": [ "https://access.scalar.com" ], From bd2ade8fd8dc9fd5f2b50bcfc7082e3c92894b33 Mon Sep 17 00:00:00 2001 From: scalarbot Date: Tue, 15 Sep 2026 21:15:23 +0000 Subject: [PATCH 5/7] feat(api)!: update schema timestamp (+1 more change) - Regenerated with generator `0.32.14` (previously `0.32.0`). - Schema `timestamp` shape changed. BREAKING CHANGE: Schema `timestamp` shape changed. Build: bOvcZYvS3NarRoMC1aix2 --- .github/workflows/release-please.yml | 14 +++++-- package.json | 3 +- scalar-sdk.manifest.json | 7 +++- scripts/publish-npm.mjs | 31 +++++++++++++++- src/core/error.ts | 16 ++++++++ tests/smoke-test.ts | 55 +++++++++++++++++----------- 6 files changed, 96 insertions(+), 30 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index d7569b3..136c17a 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -1,12 +1,20 @@ name: Release Please on: - # Fires when a human merges the platform-managed release PR into main - # (the PR's base, so its diff shows the full pending release). Regenerations and - # custom-code pushes only touch scalar-next and never run this workflow. + # A release is cut when a human merges the platform-managed release PR into + # main (the PR's base, so its diff shows the full pending release). + # Every other push here runs release-please as well — commits written straight to + # this branch included — and cuts nothing, there being no release commit at the tip. push: branches: - main + # The Scalar platform pushes these workflow files straight to main to keep them + # current between releases; that is bookkeeping, never a release. Running anyway is worse + # than pointless on a branch that has not been handed a .release-please-manifest.json yet — + # release-please fails the run outright when it cannot read one. A release commit always + # rewrites the manifest and the changelog, so this filter can never swallow one. + paths-ignore: + - '.github/workflows/**' # Manual fallback only; nothing in the automated chain depends on dispatch. workflow_dispatch: diff --git a/package.json b/package.json index e22b023..e174b7d 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,9 @@ }, "./*.js": { "types": "./dist/esm/*.d.ts", + "import": "./dist/esm/*.js", "require": "./dist/cjs/*.js", - "default": "./dist/cjs/*.js" + "default": "./dist/esm/*.js" }, "./*": { "types": "./dist/esm/*.d.ts", diff --git a/scalar-sdk.manifest.json b/scalar-sdk.manifest.json index e7baf96..7a423b0 100644 --- a/scalar-sdk.manifest.json +++ b/scalar-sdk.manifest.json @@ -1,7 +1,7 @@ { "name": "Scalar", "slug": "scalar", - "generatorVersion": "0.32.0", + "generatorVersion": "0.32.14", "servers": [ "https://access.scalar.com" ], @@ -770,7 +770,10 @@ "type": { "kind": "primitive", "type": "integer", - "validation": {} + "validation": { + "minimum": 0, + "maximum": 9007199254740991 + } } }, { diff --git a/scripts/publish-npm.mjs b/scripts/publish-npm.mjs index 71453f1..894443f 100644 --- a/scripts/publish-npm.mjs +++ b/scripts/publish-npm.mjs @@ -2,6 +2,15 @@ import { readFileSync } from 'node:fs'; import { spawnSync } from 'node:child_process'; import { pathToFileURL } from 'node:url'; +/** Package visibility this SDK publishes with, from `publish.npm.access`. */ +const ACCESS = 'public'; + +/** + * Dist-tag a stable release lands on, from `publish.npm.tag`. `null` leaves npm on its own default, + * `latest`. A prerelease derives its own tag below and never reads this. + */ +const STABLE_DIST_TAG = null; + /** Reads the package identity once so every registry operation uses the same metadata. */ export const readPackageMetadata = () => { const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')); @@ -37,8 +46,26 @@ export const publishNpm = (runner = runNpm, metadata = readPackageMetadata()) => return; } - const tag = npmDistTagForVersion(version); - const args = ['publish', '--access', 'public', ...(tag ? ['--tag', tag] : [])]; + // A prerelease's own tag wins over the configured one: `publish.npm.tag` names where *stable* + // releases land, so honouring it for a prerelease would point that tag at a prerelease build. + // + // A derived tag naming a stable line is suffixed rather than used as-is, because the two collide: + // `npmDistTagForVersion` falls back to `next` for any prerelease identifier it cannot use as a + // tag, so on a package configured with `tag: 'next'` a `1.3.0-RC.1` would otherwise publish over + // the stable line it names. + // + // Both lines are protected, not just the configured one. `latest` is what a bare `npm install` + // resolves whether or not `publish.npm.tag` moves stable releases elsewhere, so a `1.0.0-latest.1` + // on a package configured with `tag: 'next'` must not take it either. + const derived = npmDistTagForVersion(version); + const stableTags = [STABLE_DIST_TAG ?? 'latest', 'latest']; + const tag = + derived === undefined + ? STABLE_DIST_TAG + : stableTags.includes(derived) + ? `${derived}-prerelease` + : derived; + const args = ['publish', '--access', ACCESS, ...(tag ? ['--tag', tag] : [])]; console.log( tag ? `Publishing ${packageSpec} to npm with dist-tag ${tag}` : `Publishing ${packageSpec} to npm`, ); diff --git a/src/core/error.ts b/src/core/error.ts index c2dcad3..a2a0dfe 100644 --- a/src/core/error.ts +++ b/src/core/error.ts @@ -128,3 +128,19 @@ export class UnprocessableEntityError extends APIError<422, Headers> {} export class RateLimitError extends APIError<429, Headers> {} export class InternalServerError extends APIError {} + +// Each class names itself, so a caught error reports its real class rather than the inherited +// `Error` — what a log line, a `switch (error.name)`, and an error reporter grouping by name read. +ScalarError.prototype.name = 'ScalarError'; +APIError.prototype.name = 'APIError'; +APIUserAbortError.prototype.name = 'APIUserAbortError'; +APIConnectionError.prototype.name = 'APIConnectionError'; +APIConnectionTimeoutError.prototype.name = 'APIConnectionTimeoutError'; +BadRequestError.prototype.name = 'BadRequestError'; +AuthenticationError.prototype.name = 'AuthenticationError'; +PermissionDeniedError.prototype.name = 'PermissionDeniedError'; +NotFoundError.prototype.name = 'NotFoundError'; +ConflictError.prototype.name = 'ConflictError'; +UnprocessableEntityError.prototype.name = 'UnprocessableEntityError'; +RateLimitError.prototype.name = 'RateLimitError'; +InternalServerError.prototype.name = 'InternalServerError'; diff --git a/tests/smoke-test.ts b/tests/smoke-test.ts index 573458b..c0e9c6e 100644 --- a/tests/smoke-test.ts +++ b/tests/smoke-test.ts @@ -771,6 +771,17 @@ const cases: { }, ]; +/** + * How many cases run at once, capped at the number of cases there are. + * + * SCALAR_SMOKE_CONCURRENCY overrides the default; anything unparseable falls back to it. + */ +const smokeConcurrency = (caseCount: number): number => { + const override = Number.parseInt(process.env['SCALAR_SMOKE_CONCURRENCY'] ?? '', 10); + const limit = Number.isInteger(override) && override > 0 ? override : 32; + return Math.min(limit, caseCount); +}; + const main = async (): Promise => { // SCALAR_SMOKE_FILTER (comma-separated) keeps only cases whose operation name or path matches // one of the needles, so a caller can smoke-test a subset. With no filter, every case runs. @@ -788,10 +799,18 @@ const main = async (): Promise => { ) : cases; - // Run every selected case concurrently. Promise.allSettled means one failing operation never - // blocks the others, so a single run reports the status of every endpoint. - const settled = await Promise.allSettled( - selected.map(async (testCase): Promise => { + // Run the selected cases under a bounded worker pool rather than all at once. A large SDK has + // hundreds of operations, and firing every request together exceeds what the client's transport + // keeps connections for while the runner is already busy with other targets. Each worker pulls + // the next index off a shared cursor and writes into a pre-sized array, so results stay in case + // order however the workers interleave. The per-case body catches everything and never rejects, + // so one failing operation still cannot block the others. + const results: SmokeResult[] = new Array(selected.length); + let cursor = 0; + const runNext = async (): Promise => { + for (let index = cursor++; index < selected.length; index = cursor++) { + const testCase = selected[index]; + if (!testCase) continue; const startedAt = Date.now(); // `label` distinguishes the required-params run from the all-params run of the same // operation; it is omitted entirely when the operation contributed only one case. @@ -803,28 +822,20 @@ const main = async (): Promise => { }; try { await testCase.run(); - return { ...identity, status: 'passed', durationMs: Date.now() - startedAt }; + results[index] = { ...identity, status: 'passed', durationMs: Date.now() - startedAt }; } catch (error) { // Prefer the stack so a failure points at the failing SDK call; fall back to the message. const message = error instanceof Error ? (error.stack ?? error.message) : String(error); - return { ...identity, status: 'failed', durationMs: Date.now() - startedAt, error: message }; - } - }), - ); - - // allSettled never rejects, but defensively map any rejected slot to a failed result. - const results: SmokeResult[] = settled.map((result) => - result.status === 'fulfilled' - ? result.value - : { - operation: 'unknown', - method: '', - path: '', + results[index] = { + ...identity, status: 'failed', - durationMs: 0, - error: String(result.reason), - }, - ); + durationMs: Date.now() - startedAt, + error: message, + }; + } + } + }; + await Promise.all(Array.from({ length: smokeConcurrency(selected.length) }, runNext)); const failed = results.filter((result) => result.status === 'failed'); // With SCALAR_SMOKE_REPORT set, write a machine-readable report; otherwise print a table. From d1bfbf66b9a1114c9e79163fb9569159be97cda8 Mon Sep 17 00:00:00 2001 From: scalarbot Date: Tue, 15 Sep 2026 22:13:53 +0000 Subject: [PATCH 6/7] chore(api): update generated SDK content 1 generated file changed with no detected API surface change (documentation, examples, or file content). Build: Rzv5SDVsnJ3mjymKY2N70 --- src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.ts b/src/version.ts index 091efaf..78e0a69 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ // File generated from our OpenAPI spec by Scalar. See README.md for details. -export const VERSION = '0.4.1'; // x-release-please-version +export const VERSION = '0.5.0'; // x-release-please-version From 42dd613f872244f3f9de4bc81327f1ca6afe929b Mon Sep 17 00:00:00 2001 From: "scalar-docs[bot]" <148485328+scalar-docs[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:14:11 +0000 Subject: [PATCH 7/7] release: 0.5.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f1c1e58..210d290 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.0" + ".": "0.5.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 386a560..c7fa46f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.5.1](https://github.com/scalar/scalar-node/compare/v0.5.0...v0.5.1) (2026-09-15) + + +### Chores + +* **api:** update generated SDK content ([d1bfbf6](https://github.com/scalar/scalar-node/commit/d1bfbf66b9a1114c9e79163fb9569159be97cda8)) + ## [0.5.0](https://github.com/scalar/scalar-node/compare/v0.4.1...v0.5.0) (2026-09-15) diff --git a/package.json b/package.json index 2ba165f..156a023 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@scalar/sdk", - "version": "0.5.0", + "version": "0.5.1", "description": "API for managing Scalar platform resources.", "author": "Scalar", "repository": { diff --git a/src/version.ts b/src/version.ts index 78e0a69..1b1583f 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ // File generated from our OpenAPI spec by Scalar. See README.md for details. -export const VERSION = '0.5.0'; // x-release-please-version +export const VERSION = '0.5.1'; // x-release-please-version