diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6738da3..faf510f 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/steel-node'
+ if: |-
+ github.repository == 'stainless-sdks/steel-node' &&
+ !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/steel-node'
+ if: |-
+ github.repository == 'stainless-sdks/steel-node' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 7b51ca0..5e39b94 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.17.0"
+ ".": "0.18.0"
}
diff --git a/.stats.yml b/.stats.yml
index 416f1d7..35acfcc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 39
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-45efcdf3e5ccffb6e94a86be505b24b7b4ff05d8f1a2978c2a281729af68cb82.yml
-openapi_spec_hash: 9a7724672b05d44888d67b6ed0ffc7ca
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-f51ce05f6128dcdd6b500492869910d3a43737c66d0bc13c3f2e67f42362605c.yml
+openapi_spec_hash: c573fb6f26d5fb14eaf92e0a107323ec
config_hash: dce4dea59023b0a00890fa654fbfffb4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f19957..00fd031 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,34 @@
# Changelog
+## 0.18.0 (2026-03-16)
+
+Full Changelog: [v0.17.0...v0.18.0](https://github.com/steel-dev/steel-node/compare/v0.17.0...v0.18.0)
+
+### Features
+
+* **api:** api update ([84d694c](https://github.com/steel-dev/steel-node/commit/84d694cc49d7d3827e4695f64104eb0bdcefaa2a))
+* **api:** api update ([34de369](https://github.com/steel-dev/steel-node/commit/34de3694682b68fe48f799cc116caa9de8df215c))
+* **api:** api update ([95c42cd](https://github.com/steel-dev/steel-node/commit/95c42cd171f43b25f2b527608210f4c6a0ebdba8))
+
+
+### Bug Fixes
+
+* **client:** preserve URL params already embedded in path ([8d952ca](https://github.com/steel-dev/steel-node/commit/8d952ca2518c74a8844e48b3a390e56067f531db))
+* **docs/contributing:** correct pnpm link command ([e3dddca](https://github.com/steel-dev/steel-node/commit/e3dddca3f68711c46b554a84a37c5d9161c26394))
+* **internal:** skip tests that depend on mock server ([d73bebe](https://github.com/steel-dev/steel-node/commit/d73bebeca00b88e47357778c9365b332c8cbd5c2))
+* publish via npm registry in release script ([74f0eae](https://github.com/steel-dev/steel-node/commit/74f0eae3e6987b92dada862eb4ab2a2ba6a22465))
+* publish via npm registry in release script ([700090e](https://github.com/steel-dev/steel-node/commit/700090e76c67b8f6ee44efc41da77997f1b4edce))
+
+
+### Chores
+
+* **ci:** skip uploading artifacts on stainless-internal branches ([b5503bb](https://github.com/steel-dev/steel-node/commit/b5503bb501f549a5cc1b61c6e3795af9f733fe9e))
+* **internal:** codegen related update ([4e66ed3](https://github.com/steel-dev/steel-node/commit/4e66ed36fec23cc144fc4a04c2ab564c96df5afb))
+* **internal:** move stringifyQuery implementation to internal function ([ff8f1d9](https://github.com/steel-dev/steel-node/commit/ff8f1d9e4b65ab114f171c93ddba59aeded03192))
+* **test:** do not count install time for mock server timeout ([e42f0e2](https://github.com/steel-dev/steel-node/commit/e42f0e28af237b8c0fc3bb7d45334f6f4f5b5cb2))
+* update mock server docs ([782421b](https://github.com/steel-dev/steel-node/commit/782421bbe1366c326ec5b0e61b6538701d15118f))
+* update placeholder string ([c0b12a4](https://github.com/steel-dev/steel-node/commit/c0b12a4d9f1d946d3c27b819c0bbac3af17fe172))
+
## 0.17.0 (2026-02-06)
Full Changelog: [v0.16.0...v0.17.0](https://github.com/steel-dev/steel-node/compare/v0.16.0...v0.17.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fcf63ff..c2a9271 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -60,7 +60,7 @@ $ yarn link steel-sdk
# With pnpm
$ pnpm link --global
$ cd ../my-package
-$ pnpm link -—global steel-sdk
+$ pnpm link --global steel-sdk
```
## Running tests
@@ -68,7 +68,7 @@ $ pnpm link -—global steel-sdk
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
+$ ./scripts/mock
```
```sh
diff --git a/api.md b/api.md
index 4e365d1..7060742 100644
--- a/api.md
+++ b/api.md
@@ -62,7 +62,7 @@ Methods:
- client.sessions.list({ ...params }) -> SessionslistSessionsSessionsCursor
- client.sessions.computer(sessionId, { ...params }) -> SessionComputerResponse
- client.sessions.context(id) -> SessionContext
-- client.sessions.events(id) -> SessionEventsResponse
+- client.sessions.events(id, { ...params }) -> SessionEventsResponse
- client.sessions.liveDetails(id) -> SessionLiveDetailsResponse
- client.sessions.release(id) -> SessionReleaseResponse
- client.sessions.releaseAll() -> SessionReleaseAllResponse
diff --git a/package.json b/package.json
index 1487d20..8d1b622 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "steel-sdk",
- "version": "0.17.0",
+ "version": "0.18.0",
"description": "The official TypeScript library for the Steel API",
"author": "Steel ",
"types": "dist/index.d.ts",
diff --git a/scripts/mock b/scripts/mock
index 0b28f6e..bcf3b39 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -21,11 +21,22 @@ echo "==> Starting mock server with URL ${URL}"
# Run prism mock on the given spec
if [ "$1" == "--daemon" ]; then
+ # Pre-install the package so the download doesn't eat into the startup timeout
+ npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version
+
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
- # Wait for server to come online
+ # Wait for server to come online (max 30s)
echo -n "Waiting for server"
+ attempts=0
while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ attempts=$((attempts + 1))
+ if [ "$attempts" -ge 300 ]; then
+ echo
+ echo "Timed out waiting for Prism server to start"
+ cat .prism.log
+ exit 1
+ fi
echo -n "."
sleep 0.1
done
diff --git a/src/core.ts b/src/core.ts
index c55a95a..db70727 100644
--- a/src/core.ts
+++ b/src/core.ts
@@ -6,6 +6,7 @@ import {
APIConnectionTimeoutError,
APIUserAbortError,
} from './error';
+import { stringifyQuery } from './internal/utils/query';
import {
kind as shimsKind,
type Readable,
@@ -523,32 +524,20 @@ export abstract class APIClient {
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
const defaultQuery = this.defaultQuery();
- if (!isEmptyObj(defaultQuery)) {
- query = { ...defaultQuery, ...query } as Req;
+ const pathQuery = Object.fromEntries(url.searchParams);
+ if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) {
+ query = { ...pathQuery, ...defaultQuery, ...query } as Req;
}
if (typeof query === 'object' && query && !Array.isArray(query)) {
- url.search = this.stringifyQuery(query as Record);
+ url.search = this.stringifyQuery(query);
}
return url.toString();
}
- protected stringifyQuery(query: Record): string {
- return Object.entries(query)
- .filter(([_, value]) => typeof value !== 'undefined')
- .map(([key, value]) => {
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
- }
- if (value === null) {
- return `${encodeURIComponent(key)}=`;
- }
- throw new SteelError(
- `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
- );
- })
- .join('&');
+ protected stringifyQuery(query: object | Record): string {
+ return stringifyQuery(query);
}
async fetchWithTimeout(
@@ -634,9 +623,9 @@ export abstract class APIClient {
}
}
- // 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, do what it says.
+ // Otherwise calculate a default.
+ if (timeoutMillis === undefined) {
const maxRetries = options.maxRetries ?? this.maxRetries;
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
}
diff --git a/src/index.ts b/src/index.ts
index cbcabdc..5695168 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -54,6 +54,7 @@ import {
SessionComputerResponse,
SessionContext,
SessionCreateParams,
+ SessionEventsParams,
SessionEventsResponse,
SessionListParams,
SessionLiveDetailsResponse,
@@ -313,6 +314,7 @@ export declare namespace Steel {
type SessionCreateParams as SessionCreateParams,
type SessionListParams as SessionListParams,
type SessionComputerParams as SessionComputerParams,
+ type SessionEventsParams as SessionEventsParams,
type SessionReleaseParams as SessionReleaseParams,
type SessionReleaseAllParams as SessionReleaseAllParams,
};
diff --git a/src/internal/utils/query.ts b/src/internal/utils/query.ts
new file mode 100644
index 0000000..b501944
--- /dev/null
+++ b/src/internal/utils/query.ts
@@ -0,0 +1,23 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { SteelError } from '../../error';
+
+/**
+ * Basic re-implementation of `qs.stringify` for primitive types.
+ */
+export function stringifyQuery(query: object | Record) {
+ return Object.entries(query)
+ .filter(([_, value]) => typeof value !== 'undefined')
+ .map(([key, value]) => {
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
+ }
+ if (value === null) {
+ return `${encodeURIComponent(key)}=`;
+ }
+ throw new SteelError(
+ `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
+ );
+ })
+ .join('&');
+}
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 62e9810..0b2fa24 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -46,6 +46,7 @@ export {
type SessionCreateParams,
type SessionListParams,
type SessionComputerParams,
+ type SessionEventsParams,
type SessionReleaseParams,
type SessionReleaseAllParams,
} from './sessions/sessions';
diff --git a/src/resources/sessions/index.ts b/src/resources/sessions/index.ts
index e41c1e2..961a51a 100644
--- a/src/resources/sessions/index.ts
+++ b/src/resources/sessions/index.ts
@@ -23,6 +23,7 @@ export {
type SessionCreateParams,
type SessionListParams,
type SessionComputerParams,
+ type SessionEventsParams,
type SessionReleaseParams,
type SessionReleaseAllParams,
} from './sessions';
diff --git a/src/resources/sessions/sessions.ts b/src/resources/sessions/sessions.ts
index 7bdf043..c214b2f 100644
--- a/src/resources/sessions/sessions.ts
+++ b/src/resources/sessions/sessions.ts
@@ -80,8 +80,21 @@ export class Sessions extends APIResource {
/**
* This endpoint allows you to get the recorded session events in the RRWeb format
*/
- events(id: string, options?: Core.RequestOptions): Core.APIPromise {
- return this._client.get(`/v1/sessions/${id}/events`, options);
+ events(
+ id: string,
+ query?: SessionEventsParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise;
+ events(id: string, options?: Core.RequestOptions): Core.APIPromise;
+ events(
+ id: string,
+ query: SessionEventsParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(query)) {
+ return this.events(id, {}, query);
+ }
+ return this._client.get(`/v1/sessions/${id}/events`, { query, ...options });
}
/**
@@ -508,9 +521,10 @@ export interface Sessionslist {
sessions: Array;
/**
- * Total number of sessions matching the query
+ * Total number of sessions matching the query. Only included for filtered queries
+ * (e.g. status=live).
*/
- totalCount: number;
+ totalCount?: number;
}
export namespace Sessionslist {
@@ -837,6 +851,11 @@ export interface SessionCreateParams {
*/
dimensions?: SessionCreateParams.Dimensions;
+ /**
+ * Enable experimental features for the session.
+ */
+ experimentalFeatures?: Array;
+
/**
* Array of extension IDs to install in the session. Use ['all_ext'] to install all
* uploaded extensions.
@@ -2727,6 +2746,23 @@ export declare namespace SessionComputerParams {
}
}
+export interface SessionEventsParams {
+ /**
+ * Compress the events
+ */
+ compressed?: boolean;
+
+ /**
+ * Optional pagination limit
+ */
+ limit?: number;
+
+ /**
+ * Opaque pagination token. Pass the Next-Cursor header value to get the next page.
+ */
+ pointer?: string;
+}
+
export interface SessionReleaseParams {}
export interface SessionReleaseAllParams {}
@@ -2749,6 +2785,7 @@ export declare namespace Sessions {
type SessionCreateParams as SessionCreateParams,
type SessionListParams as SessionListParams,
type SessionComputerParams as SessionComputerParams,
+ type SessionEventsParams as SessionEventsParams,
type SessionReleaseParams as SessionReleaseParams,
type SessionReleaseAllParams as SessionReleaseAllParams,
};
diff --git a/src/version.ts b/src/version.ts
index 0251da7..74131f9 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.17.0'; // x-release-please-version
+export const VERSION = '0.18.0'; // x-release-please-version
diff --git a/tests/api-resources/extensions.test.ts b/tests/api-resources/extensions.test.ts
index b2867ca..494434e 100644
--- a/tests/api-resources/extensions.test.ts
+++ b/tests/api-resources/extensions.test.ts
@@ -29,7 +29,7 @@ describe('resource extensions', () => {
await expect(
client.extensions.update(
'extensionId',
- { file: await toFile(Buffer.from('# my file contents'), 'README.md'), url: 'https://example.com' },
+ { file: await toFile(Buffer.from('Example data'), 'README.md'), url: 'https://example.com' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Steel.NotFoundError);
@@ -129,7 +129,7 @@ describe('resource extensions', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.extensions.upload(
- { file: await toFile(Buffer.from('# my file contents'), 'README.md'), url: 'https://example.com' },
+ { file: await toFile(Buffer.from('Example data'), 'README.md'), url: 'https://example.com' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Steel.NotFoundError);
diff --git a/tests/api-resources/files.test.ts b/tests/api-resources/files.test.ts
index de7a347..ab17d35 100644
--- a/tests/api-resources/files.test.ts
+++ b/tests/api-resources/files.test.ts
@@ -42,7 +42,8 @@ describe('resource files', () => {
);
});
- test('download: request options instead of params are passed correctly', async () => {
+ // Mock server doesn't support application/octet-stream responses
+ test.skip('download: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(client.files.download('path', { path: '/_stainless_unknown_path' })).rejects.toThrow(
Steel.NotFoundError,
@@ -51,7 +52,7 @@ describe('resource files', () => {
test('upload: only required params', async () => {
const responsePromise = client.files.upload({
- file: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
@@ -64,7 +65,7 @@ describe('resource files', () => {
test('upload: required and optional params', async () => {
const response = await client.files.upload({
- file: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
path: 'path',
});
});
diff --git a/tests/api-resources/profiles.test.ts b/tests/api-resources/profiles.test.ts
index 799be0a..e0926d1 100644
--- a/tests/api-resources/profiles.test.ts
+++ b/tests/api-resources/profiles.test.ts
@@ -8,7 +8,7 @@ const client = new Steel({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://
describe('resource profiles', () => {
test('create: only required params', async () => {
const responsePromise = client.profiles.create({
- userDataDir: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ userDataDir: await toFile(Buffer.from('Example data'), 'README.md'),
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
@@ -21,7 +21,7 @@ describe('resource profiles', () => {
test('create: required and optional params', async () => {
const response = await client.profiles.create({
- userDataDir: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ userDataDir: await toFile(Buffer.from('Example data'), 'README.md'),
dimensions: { height: 0, width: 0 },
proxyUrl: 'https://example.com',
userAgent: 'userAgent',
@@ -30,7 +30,7 @@ describe('resource profiles', () => {
test('update: only required params', async () => {
const responsePromise = client.profiles.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
- userDataDir: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ userDataDir: await toFile(Buffer.from('Example data'), 'README.md'),
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
@@ -43,7 +43,7 @@ describe('resource profiles', () => {
test('update: required and optional params', async () => {
const response = await client.profiles.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
- userDataDir: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ userDataDir: await toFile(Buffer.from('Example data'), 'README.md'),
dimensions: { height: 0, width: 0 },
proxyUrl: 'https://example.com',
userAgent: 'userAgent',
diff --git a/tests/api-resources/sessions/files.test.ts b/tests/api-resources/sessions/files.test.ts
index 587d41b..cc343b0 100644
--- a/tests/api-resources/sessions/files.test.ts
+++ b/tests/api-resources/sessions/files.test.ts
@@ -60,14 +60,16 @@ describe('resource files', () => {
).rejects.toThrow(Steel.NotFoundError);
});
- test('download: request options instead of params are passed correctly', async () => {
+ // Mock server doesn't support application/octet-stream responses
+ test.skip('download: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.sessions.files.download('sessionId', 'path', { path: '/_stainless_unknown_path' }),
).rejects.toThrow(Steel.NotFoundError);
});
- test('downloadArchive: request options instead of params are passed correctly', async () => {
+ // Mock server doesn't support application/zip responses
+ test.skip('downloadArchive: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.sessions.files.downloadArchive('sessionId', { path: '/_stainless_unknown_path' }),
@@ -76,7 +78,7 @@ describe('resource files', () => {
test('upload: only required params', async () => {
const responsePromise = client.sessions.files.upload('sessionId', {
- file: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
});
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
@@ -89,7 +91,7 @@ describe('resource files', () => {
test('upload: required and optional params', async () => {
const response = await client.sessions.files.upload('sessionId', {
- file: await toFile(Buffer.from('# my file contents'), 'README.md'),
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
path: 'path',
});
});
diff --git a/tests/api-resources/sessions/sessions.test.ts b/tests/api-resources/sessions/sessions.test.ts
index ee590b0..244db8d 100644
--- a/tests/api-resources/sessions/sessions.test.ts
+++ b/tests/api-resources/sessions/sessions.test.ts
@@ -32,6 +32,7 @@ describe('resource sessions', () => {
debugConfig: { interactive: true, systemCursor: true },
deviceConfig: { device: 'desktop' },
dimensions: { height: -9007199254740991, width: -9007199254740991 },
+ experimentalFeatures: ['string'],
extensionIds: ['string'],
headless: true,
isSelenium: true,
@@ -220,6 +221,21 @@ describe('resource sessions', () => {
).rejects.toThrow(Steel.NotFoundError);
});
+ test('events: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.sessions.events(
+ '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
+ {
+ compressed: true,
+ limit: 1,
+ pointer: 'pointer',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(Steel.NotFoundError);
+ });
+
test('liveDetails', async () => {
const responsePromise = client.sessions.liveDetails('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');
const rawResponse = await responsePromise.asResponse();
diff --git a/tests/stringifyQuery.test.ts b/tests/stringifyQuery.test.ts
index 0ae97de..5622892 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 { Steel } from 'steel-sdk';
-
-const { stringifyQuery } = Steel.prototype as any;
+import { stringifyQuery } from 'steel-sdk/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);
});