From ee56b56d65673a9a6dd92552e12906665ed3256a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 21:27:13 +0000 Subject: [PATCH 1/3] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 2702d73..3004020 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 7 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/unlayer%2Funlayer-48f00d1c04c23fb4d1cb7cf4af4f56b0c920d758c1f06e06e5373e5b15e9c27d.yml openapi_spec_hash: 6ee2a94bb9840aceb4a6161c724ce46c -config_hash: 249869757b6eb98ae3d58f2a47ce21e2 +config_hash: c8d97d58d67dad9eeb65eb58fc781724 From a3828431e022b0c294eea5dd6d3dfec91dc50f3c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 05:12:35 +0000 Subject: [PATCH 2/3] chore(internal): move stringifyQuery implementation to internal function --- src/client.ts | 22 +++++----------------- src/internal/utils.ts | 1 + src/internal/utils/query.ts | 23 +++++++++++++++++++++++ tests/stringifyQuery.test.ts | 6 ++---- 4 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 src/internal/utils/query.ts diff --git a/src/client.ts b/src/client.ts index 889cbc0..0b9842c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -11,6 +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 { stringifyQuery } from './internal/utils/query'; import { VERSION } from './version'; import * as Errors from './core/error'; import * as Pagination from './core/pagination'; @@ -271,21 +272,8 @@ export class Unlayer { /** * Basic re-implementation of `qs.stringify` for primitive types. */ - 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 Errors.UnlayerError( - `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); } private getUserAgent(): string { @@ -322,7 +310,7 @@ export class Unlayer { } if (typeof query === 'object' && query && !Array.isArray(query)) { - url.search = this.stringifyQuery(query as Record); + url.search = this.stringifyQuery(query); } return url.toString(); @@ -786,7 +774,7 @@ export class Unlayer { ) { 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..bd0eb5e --- /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 { UnlayerError } from '../../core/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 UnlayerError( + `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/tests/stringifyQuery.test.ts b/tests/stringifyQuery.test.ts index 4f47883..37eca7e 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 { Unlayer } from '@unlayer/sdk'; - -const { stringifyQuery } = Unlayer.prototype as any; +import { stringifyQuery } from '@unlayer/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); }); From c6204bdf620e82a1b0de3859c74a0b04ddb220be Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 05:10:29 +0000 Subject: [PATCH 3/3] chore(internal): codegen related update --- src/client.ts | 9 +++++++++ src/resources/convert/full-to-simple.ts | 3 +++ src/resources/convert/simple-to-full.ts | 3 +++ src/resources/projects.ts | 3 +++ src/resources/templates.ts | 3 +++ src/resources/workspaces.ts | 3 +++ 6 files changed, 24 insertions(+) diff --git a/src/client.ts b/src/client.ts index 0b9842c..c6731e9 100644 --- a/src/client.ts +++ b/src/client.ts @@ -801,8 +801,17 @@ export class Unlayer { static toFile = Uploads.toFile; convert: API.Convert = new API.Convert(this); + /** + * Project details and configuration. + */ projects: API.Projects = new API.Projects(this); + /** + * Template management and retrieval. + */ templates: API.Templates = new API.Templates(this); + /** + * Workspace access and management. + */ workspaces: API.Workspaces = new API.Workspaces(this); } diff --git a/src/resources/convert/full-to-simple.ts b/src/resources/convert/full-to-simple.ts index 44e02b9..ceb1e69 100644 --- a/src/resources/convert/full-to-simple.ts +++ b/src/resources/convert/full-to-simple.ts @@ -4,6 +4,9 @@ import { APIResource } from '../../core/resource'; import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; +/** + * Design schema conversion between Full and Simple formats. + */ export class FullToSimple extends APIResource { /** * Convert design json from Full to Simple schema. diff --git a/src/resources/convert/simple-to-full.ts b/src/resources/convert/simple-to-full.ts index c1051de..2790174 100644 --- a/src/resources/convert/simple-to-full.ts +++ b/src/resources/convert/simple-to-full.ts @@ -4,6 +4,9 @@ import { APIResource } from '../../core/resource'; import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; +/** + * Design schema conversion between Full and Simple formats. + */ export class SimpleToFull extends APIResource { /** * Convert design json from Simple to Full schema. diff --git a/src/resources/projects.ts b/src/resources/projects.ts index 6b97668..0d15122 100644 --- a/src/resources/projects.ts +++ b/src/resources/projects.ts @@ -5,6 +5,9 @@ import { APIPromise } from '../core/api-promise'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; +/** + * Project details and configuration. + */ export class Projects extends APIResource { /** * Get project details by ID. diff --git a/src/resources/templates.ts b/src/resources/templates.ts index 38eef4b..8d1cbb8 100644 --- a/src/resources/templates.ts +++ b/src/resources/templates.ts @@ -6,6 +6,9 @@ import { CursorPage, type CursorPageParams, PagePromise } from '../core/paginati import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; +/** + * Template management and retrieval. + */ export class Templates extends APIResource { /** * Get template by ID. diff --git a/src/resources/workspaces.ts b/src/resources/workspaces.ts index e51624e..4b338e1 100644 --- a/src/resources/workspaces.ts +++ b/src/resources/workspaces.ts @@ -5,6 +5,9 @@ import { APIPromise } from '../core/api-promise'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; +/** + * Workspace access and management. + */ export class Workspaces extends APIResource { /** * Get a specific workspace by ID with its projects. Requires a Personal Access