From 2f70ad9e95854605f9f38c401d49f8422d62af75 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 08:52:42 +0000 Subject: [PATCH 01/46] fix(internal): return in castToError instead of throwing (#43) --- src/internal/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/errors.ts b/src/internal/errors.ts index 653a6ec..82c7b14 100644 --- a/src/internal/errors.ts +++ b/src/internal/errors.ts @@ -22,7 +22,7 @@ export const castToError = (err: any): Error => { // @ts-ignore - not all envs have native support for cause yet if (err.cause && !error.cause) error.cause = err.cause; if (err.name) error.name = err.name; - throw error; + return error; } } catch {} try { From bd9e5361115c7f9adc8c8d9798f38a04b55ab03c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 09:11:16 +0000 Subject: [PATCH 02/46] chore(internal): remove unnecessary todo (#45) --- src/internal/parse.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 799b71c..2085087 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -34,8 +34,6 @@ export async function defaultParseResponse(client: Gitpod, props: APIResponse } const text = await response.text(); - - // TODO handle blob, arraybuffer, other content types, etc. return text as unknown as T; })(); loggerFor(client).debug( From 6450e47a5f12103274528a67028b91a01b9c55b8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 04:06:07 +0000 Subject: [PATCH 03/46] docs: update URLs from stainlessapi.com to stainless.com (#46) More details at https://www.stainless.com/changelog/stainless-com --- README.md | 2 +- SECURITY.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e071c46..ae0223a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This library provides convenient access to the Gitpod REST API from server-side The REST API documentation can be found on [docs.gitpod.io](https://docs.gitpod.io). The full API of this library can be found in [api.md](api.md). -It is generated with [Stainless](https://www.stainlessapi.com/). +It is generated with [Stainless](https://www.stainless.com/). ## Installation diff --git a/SECURITY.md b/SECURITY.md index 0985c82..2b0ed90 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,9 +2,9 @@ ## Reporting Security Issues -This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. +This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. -To report a security issue, please contact the Stainless team at security@stainlessapi.com. +To report a security issue, please contact the Stainless team at security@stainless.com. ## Responsible Disclosure From cd888bc3c16d0d2cbf3b3c96ab23dc7d46360598 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:33:40 +0000 Subject: [PATCH 04/46] chore(client): only accept standard types for file uploads (#47) --- scripts/build | 4 +- src/client.ts | 4 +- src/internal/polyfill/file.node.d.ts | 9 - src/internal/polyfill/file.node.js | 17 -- src/internal/polyfill/file.node.mjs | 9 - src/internal/shims.ts | 56 ----- .../{polyfill => shims}/crypto.node.d.ts | 0 .../{polyfill => shims}/crypto.node.js | 0 .../{polyfill => shims}/crypto.node.mjs | 0 src/internal/shims/file.node.d.ts | 20 ++ src/internal/shims/file.node.js | 11 + src/internal/shims/file.node.mjs | 2 + src/internal/to-file.ts | 152 ++++++++++++ src/internal/uploads.ts | 220 ++++-------------- src/internal/utils/uuid.ts | 2 +- src/uploads.ts | 3 +- tests/uploads.test.ts | 38 ++- 17 files changed, 267 insertions(+), 280 deletions(-) delete mode 100644 src/internal/polyfill/file.node.d.ts delete mode 100644 src/internal/polyfill/file.node.js delete mode 100644 src/internal/polyfill/file.node.mjs rename src/internal/{polyfill => shims}/crypto.node.d.ts (100%) rename src/internal/{polyfill => shims}/crypto.node.js (100%) rename src/internal/{polyfill => shims}/crypto.node.mjs (100%) create mode 100644 src/internal/shims/file.node.d.ts create mode 100644 src/internal/shims/file.node.js create mode 100644 src/internal/shims/file.node.mjs create mode 100644 src/internal/to-file.ts diff --git a/scripts/build b/scripts/build index 08bfe2e..7b100ad 100755 --- a/scripts/build +++ b/scripts/build @@ -40,8 +40,8 @@ cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts -mkdir -p dist/internal/polyfill -cp src/internal/polyfill/*.{mjs,js,d.ts} dist/internal/polyfill +mkdir -p dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/client.ts b/src/client.ts index 9836801..8c0af2b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -726,7 +726,9 @@ export class Gitpod { const timeout = setTimeout(() => controller.abort(), ms); - const isReadableBody = Shims.isReadableLike(options.body); + const isReadableBody = + ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || + (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body); const fetchOptions: RequestInit = { signal: controller.signal as any, diff --git a/src/internal/polyfill/file.node.d.ts b/src/internal/polyfill/file.node.d.ts deleted file mode 100644 index b2a59bf..0000000 --- a/src/internal/polyfill/file.node.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -export {}; diff --git a/src/internal/polyfill/file.node.js b/src/internal/polyfill/file.node.js deleted file mode 100644 index eba997e..0000000 --- a/src/internal/polyfill/file.node.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -if (typeof require !== 'undefined') { - if (!globalThis.File) { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // buffer module. - globalThis.File = [require][0]('node:buffer').File; - } catch (e) {} - } -} diff --git a/src/internal/polyfill/file.node.mjs b/src/internal/polyfill/file.node.mjs deleted file mode 100644 index 520dcb8..0000000 --- a/src/internal/polyfill/file.node.mjs +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -import './file.node.js'; diff --git a/src/internal/shims.ts b/src/internal/shims.ts index cb91e94..95b03fb 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -20,62 +20,6 @@ export function getDefaultFetch(): Fetch { ); } -/** - * A minimal copy of the NodeJS `stream.Readable` class so that we can - * accept the NodeJS types in certain places, e.g. file uploads - * - * https://nodejs.org/api/stream.html#class-streamreadable - */ -export interface ReadableLike { - readable: boolean; - readonly readableEnded: boolean; - readonly readableFlowing: boolean | null; - readonly readableHighWaterMark: number; - readonly readableLength: number; - readonly readableObjectMode: boolean; - destroyed: boolean; - read(size?: number): any; - pause(): this; - resume(): this; - isPaused(): boolean; - destroy(error?: Error): this; - [Symbol.asyncIterator](): AsyncIterableIterator; -} - -/** - * Determines if the given value looks like a NodeJS `stream.Readable` - * object and that it is readable, i.e. has not been consumed. - * - * https://nodejs.org/api/stream.html#class-streamreadable - */ -export function isReadableLike(value: any) { - // We declare our own class of Readable here, so it's not feasible to - // do an 'instanceof' check. Instead, check for Readable-like properties. - return !!value && value.readable === true && typeof value.read === 'function'; -} - -/** - * A minimal copy of the NodeJS `fs.ReadStream` class for usage within file uploads. - * - * https://nodejs.org/api/fs.html#class-fsreadstream - */ -export interface FsReadStreamLike extends ReadableLike { - path: {}; // real type is string | Buffer but we can't reference `Buffer` here -} - -/** - * Determines if the given value looks like a NodeJS `fs.ReadStream` - * object. - * - * This just checks if the object matches our `Readable` interface - * and defines a `path` property, there may be false positives. - * - * https://nodejs.org/api/fs.html#class-fsreadstream - */ -export function isFsReadStreamLike(value: any): value is FsReadStreamLike { - return isReadableLike(value) && 'path' in value; -} - type ReadableStreamArgs = ConstructorParameters; export function makeReadableStream(...args: ReadableStreamArgs): ReadableStream { diff --git a/src/internal/polyfill/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts similarity index 100% rename from src/internal/polyfill/crypto.node.d.ts rename to src/internal/shims/crypto.node.d.ts diff --git a/src/internal/polyfill/crypto.node.js b/src/internal/shims/crypto.node.js similarity index 100% rename from src/internal/polyfill/crypto.node.js rename to src/internal/shims/crypto.node.js diff --git a/src/internal/polyfill/crypto.node.mjs b/src/internal/shims/crypto.node.mjs similarity index 100% rename from src/internal/polyfill/crypto.node.mjs rename to src/internal/shims/crypto.node.mjs diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts new file mode 100644 index 0000000..9dc6b2f --- /dev/null +++ b/src/internal/shims/file.node.d.ts @@ -0,0 +1,20 @@ +// The infer is to make TS show it as a nice union type, +// instead of literally `ConstructorParameters[0]` +type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; +/** + * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. + */ +declare class FallbackFile extends Blob { + constructor(sources: FallbackBlobSource, fileName: string, options?: any); + /** + * The name of the `File`. + */ + readonly name: string; + /** + * The last modified date of the `File`. + */ + readonly lastModified: number; +} +export type File = InstanceType; +export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor +: typeof FallbackFile; diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js new file mode 100644 index 0000000..3f8c2ed --- /dev/null +++ b/src/internal/shims/file.node.js @@ -0,0 +1,11 @@ +if (typeof require !== 'undefined') { + if (globalThis.File) { + exports.File = globalThis.File; + } else { + try { + // Use [require][0](...) and not require(...) so bundlers don't try to bundle the + // buffer module. + exports.File = [require][0]('node:buffer').File; + } catch (e) {} + } +} diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs new file mode 100644 index 0000000..1f103f5 --- /dev/null +++ b/src/internal/shims/file.node.mjs @@ -0,0 +1,2 @@ +import * as mod from './file.node.js'; +export const File = globalThis.File || mod.File; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts new file mode 100644 index 0000000..69b76d3 --- /dev/null +++ b/src/internal/to-file.ts @@ -0,0 +1,152 @@ +import { File } from './shims/file.node.js'; +import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; +import type { FilePropertyBag } from './builtin-types'; + +type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; + +/** + * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc. + * Don't add arrayBuffer here, node-fetch doesn't have it + */ +interface BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ + readonly size: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ + readonly type: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ + text(): Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ + slice(start?: number, end?: number): BlobLike; +} + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.size === 'number' && + typeof value.type === 'string' && + typeof value.text === 'function' && + typeof value.slice === 'function' && + typeof value.arrayBuffer === 'function'; + +/** + * Intended to match DOM File, node:buffer File, undici File, etc. + */ +interface FileLike extends BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ + readonly lastModified: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ + readonly name?: string | undefined; +} + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.name === 'string' && + typeof value.lastModified === 'number' && + isBlobLike(value); + +/** + * Intended to match DOM Response, node-fetch Response, undici Response, etc. + */ +export interface ResponseLike { + url: string; + blob(): Promise; +} + +const isResponseLike = (value: any): value is ResponseLike => + value != null && + typeof value === 'object' && + typeof value.url === 'string' && + typeof value.blob === 'function'; + +export type ToFileInput = + | FileLike + | ResponseLike + | Exclude + | AsyncIterable; + +/** + * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats + * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s + * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible + * @param {Object=} options additional properties + * @param {string=} options.type the MIME type of the content + * @param {number=} options.lastModified the last modified timestamp + * @returns a {@link File} with the given properties + */ +export async function toFile( + value: ToFileInput | PromiseLike, + name?: string | null | undefined, + options?: FilePropertyBag | undefined, +): Promise { + // If it's a promise, resolve it. + value = await value; + + // If we've been given a `File` we don't need to do anything + if (isFileLike(value)) { + if (File && value instanceof File) { + return value; + } + return makeFile([await value.arrayBuffer()], value.name); + } + + if (isResponseLike(value)) { + const blob = await value.blob(); + name ||= new URL(value.url).pathname.split(/[\\/]/).pop(); + + return makeFile(await getBytes(blob), name, options); + } + + const parts = await getBytes(value); + + name ||= getName(value); + + if (!options?.type) { + const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); + if (typeof type === 'string') { + options = { ...options, type }; + } + } + + return makeFile(parts, name, options); +} + +async function getBytes(value: BlobLikePart | AsyncIterable): Promise> { + let parts: Array = []; + if ( + typeof value === 'string' || + ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. + value instanceof ArrayBuffer + ) { + parts.push(value); + } else if (isBlobLike(value)) { + parts.push(value instanceof Blob ? value : await value.arrayBuffer()); + } else if ( + isAsyncIterable(value) // includes Readable, ReadableStream, etc. + ) { + for await (const chunk of value) { + parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating? + } + } else { + const constructor = value?.constructor?.name; + throw new Error( + `Unexpected data type: ${typeof value}${ + constructor ? `; constructor: ${constructor}` : '' + }${propsForError(value)}`, + ); + } + + return parts; +} + +function propsForError(value: unknown): string { + if (typeof value !== 'object' || value === null) return ''; + const props = Object.getOwnPropertyNames(value); + return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; +} diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index ee2029c..54431c1 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,11 +1,16 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; -import { isFsReadStreamLike, type FsReadStreamLike } from './shims'; import type { Gitpod } from '../client'; -import './polyfill/file.node.js'; +import { File } from './shims/file.node.js'; +import { ReadableStreamFrom } from './shims'; -type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; -type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; +export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; +type FsReadStream = AsyncIterable & { path: string | { toString(): string } }; + +// https://github.com/oven-sh/bun/issues/5980 +interface BunFile extends Blob { + readonly name?: string | undefined; +} /** * Typically, this is a native "File" class. @@ -16,188 +21,41 @@ type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; * For convenience, you can also pass a fetch Response, or in Node, * the result of fs.createReadStream(). */ -export type Uploadable = FileLike | ResponseLike | FsReadStreamLike; - -/** - * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc. - * Don't add arrayBuffer here, node-fetch doesn't have it - */ -interface BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ - readonly size: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ - readonly type: string; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ - text(): Promise; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ - slice(start?: number, end?: number): BlobLike; -} - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => - value != null && - typeof value === 'object' && - typeof value.size === 'number' && - typeof value.type === 'string' && - typeof value.text === 'function' && - typeof value.slice === 'function' && - typeof value.arrayBuffer === 'function'; - -/** - * Intended to match DOM File, node:buffer File, undici File, etc. - */ -interface FileLike extends BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ - readonly lastModified: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ - readonly name?: string | undefined; -} -declare var FileClass: { - prototype: FileLike; - new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike; -}; - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise } => - value != null && - typeof value === 'object' && - typeof value.name === 'string' && - typeof value.lastModified === 'number' && - isBlobLike(value); - -/** - * Intended to match DOM Response, node-fetch Response, undici Response, etc. - */ -export interface ResponseLike { - url: string; - blob(): Promise; -} - -const isResponseLike = (value: any): value is ResponseLike => - value != null && - typeof value === 'object' && - typeof value.url === 'string' && - typeof value.blob === 'function'; - -const isUploadable = (value: any): value is Uploadable => { - return isFileLike(value) || isResponseLike(value) || isFsReadStreamLike(value); -}; - -type ToFileInput = Uploadable | Exclude | AsyncIterable; +export type Uploadable = File | Response | FsReadStream | BunFile; /** * Construct a `File` instance. This is used to ensure a helpful error is thrown - * for environments that don't define a global `File` yet and so that we don't - * accidentally rely on a global `File` type in our annotations. + * for environments that don't define a global `File` yet. */ -function makeFile(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike { - const File = (globalThis as any).File as typeof FileClass | undefined; +export function makeFile( + fileBits: BlobPart[], + fileName: string | undefined, + options?: FilePropertyBag, +): File { if (typeof File === 'undefined') { throw new Error('`File` is not defined as a global which is required for file uploads'); } - return new File(fileBits, fileName, options); + return new File(fileBits as any, fileName ?? 'unknown_file', options); } -/** - * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats - * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s - * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible - * @param {Object=} options additional properties - * @param {string=} options.type the MIME type of the content - * @param {number=} options.lastModified the last modified timestamp - * @returns a {@link File} with the given properties - */ -export async function toFile( - value: ToFileInput | PromiseLike, - name?: string | null | undefined, - options?: FilePropertyBag | undefined, -): Promise { - // If it's a promise, resolve it. - value = await value; - - // If we've been given a `File` we don't need to do anything - if (isFileLike(value)) { - const File = (globalThis as any).File as typeof FileClass | undefined; - if (File && value instanceof File) { - return value; - } - return makeFile([await value.arrayBuffer()], value.name ?? 'unknown_file'); - } - - if (isResponseLike(value)) { - const blob = await value.blob(); - name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file'; - - return makeFile(await getBytes(blob), name, options); - } - - const parts = await getBytes(value); - - name ||= getName(value) ?? 'unknown_file'; - - if (!options?.type) { - const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); - if (typeof type === 'string') { - options = { ...options, type }; - } - } - - return makeFile(parts, name, options); -} - -export async function getBytes( - value: Uploadable | BlobLikePart | AsyncIterable, -): Promise> { - let parts: Array = []; - if ( - typeof value === 'string' || - ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. - value instanceof ArrayBuffer - ) { - parts.push(value); - } else if (isBlobLike(value)) { - parts.push(value instanceof Blob ? value : await value.arrayBuffer()); - } else if ( - isAsyncIterableIterator(value) // includes Readable, ReadableStream, etc. - ) { - for await (const chunk of value) { - parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating? - } - } else { - const constructor = value?.constructor?.name; - throw new Error( - `Unexpected data type: ${typeof value}${ - constructor ? `; constructor: ${constructor}` : '' - }${propsForError(value)}`, - ); - } - - return parts; -} - -function propsForError(value: unknown): string { - if (typeof value !== 'object' || value === null) return ''; - const props = Object.getOwnPropertyNames(value); - return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; -} - -function getName(value: unknown): string | undefined { +export function getName(value: any): string | undefined { return ( - (typeof value === 'object' && - value !== null && - (('name' in value && String(value.name)) || - ('filename' in value && String(value.filename)) || - ('path' in value && String(value.path).split(/[\\/]/).pop()))) || - undefined + ( + (typeof value === 'object' && + value !== null && + (('name' in value && value.name && String(value.name)) || + ('url' in value && value.url && String(value.url)) || + ('filename' in value && value.filename && String(value.filename)) || + ('path' in value && value.path && String(value.path)))) || + '' + ) + .split(/[\\/]/) + .pop() || undefined ); } -const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator => +export const isAsyncIterable = (value: any): value is AsyncIterable => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; /** @@ -268,6 +126,15 @@ export const createForm = async >( return form; }; +// We check for Blob not File because Bun.File doesn't inherit from File, +// but they both inherit from Blob and have a `name` property at runtime. +const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value); + +const isUploadable = (value: unknown) => + typeof value === 'object' && + value !== null && + (value instanceof Response || isAsyncIterable(value) || isNamedBlob(value)); + const hasUploadableValue = (value: unknown): boolean => { if (isUploadable(value)) return true; if (Array.isArray(value)) return value.some(hasUploadableValue); @@ -290,9 +157,12 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis // TODO: make nested formats configurable if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { form.append(key, String(value)); - } else if (isUploadable(value)) { - const file = await toFile(value); - form.append(key, file as any); + } else if (value instanceof Response) { + form.append(key, makeFile([await value.blob()], getName(value))); + } else if (isAsyncIterable(value)) { + form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); + } else if (isNamedBlob(value)) { + form.append(key, value, getName(value)); } else if (Array.isArray(value)) { await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); } else if (typeof value === 'object') { diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 6c43f81..1349c42 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { crypto } from '../polyfill/crypto.node'; +import { crypto } from '../shims/crypto.node.js'; /** * https://stackoverflow.com/a/2117523 diff --git a/src/uploads.ts b/src/uploads.ts index 77b6576..79d3073 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1 +1,2 @@ -export { type Uploadable, toFile } from './internal/uploads'; +export { type Uploadable } from './internal/uploads'; +export { toFile, type ToFileInput } from './internal/to-file'; diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 5758464..0fc3454 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import type { ResponseLike } from '@gitpod/sdk/internal/uploads'; +import type { ResponseLike } from '@gitpod/sdk/internal/to-file'; import { toFile } from '@gitpod/sdk/uploads'; class MyClass { @@ -13,6 +13,12 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon }; } +beforeEach(() => { + // The file shim captures the global File object when it's first imported. + // Reset modules before each test so we can test the error thrown when it's undefined. + jest.resetModules(); +}); + describe('toFile', () => { it('throws a helpful error for mismatched types', async () => { await expect( @@ -62,15 +68,29 @@ describe('toFile', () => { expect(file.name).toEqual('input.jsonl'); expect(file.type).toBe('jsonl'); }); + + it('is assignable to File and Blob', async () => { + const input = new File(['foo'], 'input.jsonl', { type: 'jsonl' }); + const result = await toFile(input); + const file: File = result; + const blob: Blob = result; + void file, blob; + }); }); -test('missing File error message', async () => { - // @ts-ignore - globalThis.File = undefined; +describe('missing File error message', () => { + beforeEach(() => { + // @ts-ignore + globalThis.File = undefined; + require('node:buffer').File = undefined; + }); - await expect( - toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), - ).rejects.toMatchInlineSnapshot( - `[Error: \`File\` is not defined as a global which is required for file uploads]`, - ); + test('is thrown', async () => { + const uploads = await import('@gitpod/sdk/uploads'); + await expect( + uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), + ).rejects.toMatchInlineSnapshot( + `[Error: \`File\` is not defined as a global which is required for file uploads]`, + ); + }); }); From c1031bd67090cc27d55472a5a32ee70df9ee781e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:40:09 +0000 Subject: [PATCH 05/46] chore(internal): fix tests failing on node v18 (#48) --- tests/uploads.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 0fc3454..a118892 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,6 +1,7 @@ import fs from 'fs'; import type { ResponseLike } from '@gitpod/sdk/internal/to-file'; import { toFile } from '@gitpod/sdk/uploads'; +import { File } from 'node:buffer'; class MyClass { name: string = 'foo'; From 41da630123709c225f8c173bbd2aace382d0e865 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:41:57 +0000 Subject: [PATCH 06/46] chore(internal): constrain synckit dev dependency (#49) --- package.json | 3 +++ yarn.lock | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d59480b..dae603a 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,9 @@ "typescript": "^4.8.2", "typescript-eslint": "^8.24.0" }, + "resolutions": { + "synckit": "0.8.8" + }, "imports": { "@gitpod/sdk": ".", "@gitpod/sdk/*": "./src/*" diff --git a/yarn.lock b/yarn.lock index 6bd4ab2..6c01b49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3317,10 +3317,10 @@ 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.9.1: - version "0.9.2" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" - integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw== +synckit@0.8.8, synckit@^0.9.1: + version "0.8.8" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== dependencies: "@pkgr/core" "^0.1.0" tslib "^2.6.2" From 1262a7bcd5e0619e1eaef399ee967b629c79ce09 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:44:15 +0000 Subject: [PATCH 07/46] fix(client): fix TypeError with undefined File (#50) --- src/internal/uploads.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 54431c1..e09bcbb 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -128,7 +128,8 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. -const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value); +const isNamedBlob = (value: object) => + (File && value instanceof File) || (value instanceof Blob && 'name' in value); const isUploadable = (value: unknown) => typeof value === 'object' && From e1e0fb509bfd526c9a8183480ad88330f0c7b240 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:46:13 +0000 Subject: [PATCH 08/46] fix(internal): clean up undefined File test (#51) --- tests/uploads.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index a118892..f320eea 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -14,12 +14,6 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon }; } -beforeEach(() => { - // The file shim captures the global File object when it's first imported. - // Reset modules before each test so we can test the error thrown when it's undefined. - jest.resetModules(); -}); - describe('toFile', () => { it('throws a helpful error for mismatched types', async () => { await expect( @@ -80,11 +74,23 @@ describe('toFile', () => { }); describe('missing File error message', () => { + let prevFile: unknown; beforeEach(() => { + // The file shim captures the global File object when it's first imported. + // Reset modules before each test so we can test the error thrown when it's undefined. + jest.resetModules(); + // @ts-ignore + prevFile = globalThis.File; // @ts-ignore globalThis.File = undefined; require('node:buffer').File = undefined; }); + afterEach(() => { + // Clean up + // @ts-ignore + globalThis.File = prevFile; + jest.resetModules(); + }); test('is thrown', async () => { const uploads = await import('@gitpod/sdk/uploads'); From 2eded46344af89fbaef371ab685056b8952aa946 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:47:26 +0000 Subject: [PATCH 09/46] fix(tests): manually reset node:buffer File (#52) --- tests/uploads.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index f320eea..7b28bb5 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -74,21 +74,25 @@ describe('toFile', () => { }); describe('missing File error message', () => { - let prevFile: unknown; + let prevGlobalFile: unknown; + let prevNodeFile: unknown; beforeEach(() => { // The file shim captures the global File object when it's first imported. // Reset modules before each test so we can test the error thrown when it's undefined. jest.resetModules(); + const buffer = require('node:buffer'); // @ts-ignore - prevFile = globalThis.File; + prevGlobalFile = globalThis.File; + prevNodeFile = buffer.File; // @ts-ignore globalThis.File = undefined; - require('node:buffer').File = undefined; + buffer.File = undefined; }); afterEach(() => { // Clean up // @ts-ignore - globalThis.File = prevFile; + globalThis.File = prevGlobalFile; + require('node:buffer').File = prevNodeFile; jest.resetModules(); }); From 54a7db864f182bd872aeceae04747930a3e419a7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 10:43:21 +0000 Subject: [PATCH 10/46] chore(types): improved go to definition on fetchOptions (#53) --- src/internal/types.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/internal/types.ts b/src/internal/types.ts index 50c16e9..c3bce5a 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -6,14 +6,6 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; export type KeysEnum = { [P in keyof Required]: true }; type NotAny = [unknown] extends [T] ? never : T; -type Literal = PropertyKey extends T ? never : T; -type MappedLiteralKeys = T extends any ? Literal : never; -type MappedIndex = - T extends any ? - K extends keyof T ? - T[K] - : never - : never; /** * Some environments overload the global fetch function, and Parameters only gets the last signature. @@ -93,6 +85,6 @@ type RequestInits = * This type contains `RequestInit` options that may be available on the current runtime, * including per-platform extensions like `dispatcher`, `agent`, `client`, etc. */ -export type MergedRequestInit = { - [K in MappedLiteralKeys]?: MappedIndex | undefined; -}; +export type MergedRequestInit = RequestInits & + /** We don't include these in the types as they'll be overridden for every request. */ + Partial>; From 25092c5070acc3602094bf34f304105cb7bd7157 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 11:28:04 +0000 Subject: [PATCH 11/46] chore(docs): improve docs for withResponse/asResponse (#54) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ae0223a..0cbfd5f 100644 --- a/README.md +++ b/README.md @@ -171,8 +171,10 @@ while (page.hasNextPage()) { ### Accessing raw Response data (e.g., headers) The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return. +This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic. You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data. +Unlike `.asResponse()` this method consumes the body, returning once it is parsed. ```ts From 71a1bef58884eb34434a3e590cf0942c8166d33b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 06:44:38 +0000 Subject: [PATCH 12/46] chore(internal): codegen related update (#55) --- scripts/bootstrap | 2 +- src/internal/parse.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/bootstrap b/scripts/bootstrap index 05dd47a..0af58e2 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ]; then brew bundle check >/dev/null 2>&1 || { echo "==> Installing Homebrew dependencies…" brew bundle diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 2085087..a12647d 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -26,8 +26,8 @@ export async function defaultParseResponse(client: Gitpod, props: APIResponse } const contentType = response.headers.get('content-type'); - const isJSON = - contentType?.includes('application/json') || contentType?.includes('application/vnd.api+json'); + const mediaType = contentType?.split(';')[0]?.trim(); + const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); if (isJSON) { const json = await response.json(); return json as T; From 6431dc9927a315b9faf1e906c95930bcec65f3d5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 04:40:14 +0000 Subject: [PATCH 13/46] chore(internal): remove extra empty newlines (#56) --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3530dc..0312165 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,4 +63,3 @@ jobs: - name: Run tests run: ./scripts/test - From 23166e607ec2b8915a97e974e09cdc0abdbc6c23 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 04:50:04 +0000 Subject: [PATCH 14/46] fix(exports): ensure resource imports don't require /index (#57) --- src/resources/environments.ts | 3 +++ src/resources/environments/automations.ts | 3 +++ src/resources/environments/automations/tasks.ts | 3 +++ src/resources/organizations.ts | 3 +++ src/resources/projects.ts | 3 +++ src/resources/runners.ts | 3 +++ src/resources/runners/configurations.ts | 3 +++ src/resources/users.ts | 3 +++ 8 files changed, 24 insertions(+) create mode 100644 src/resources/environments.ts create mode 100644 src/resources/environments/automations.ts create mode 100644 src/resources/environments/automations/tasks.ts create mode 100644 src/resources/organizations.ts create mode 100644 src/resources/projects.ts create mode 100644 src/resources/runners.ts create mode 100644 src/resources/runners/configurations.ts create mode 100644 src/resources/users.ts diff --git a/src/resources/environments.ts b/src/resources/environments.ts new file mode 100644 index 0000000..85fdba4 --- /dev/null +++ b/src/resources/environments.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './environments/index'; diff --git a/src/resources/environments/automations.ts b/src/resources/environments/automations.ts new file mode 100644 index 0000000..e13af42 --- /dev/null +++ b/src/resources/environments/automations.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './automations/index'; diff --git a/src/resources/environments/automations/tasks.ts b/src/resources/environments/automations/tasks.ts new file mode 100644 index 0000000..a93e814 --- /dev/null +++ b/src/resources/environments/automations/tasks.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './tasks/index'; diff --git a/src/resources/organizations.ts b/src/resources/organizations.ts new file mode 100644 index 0000000..61ddaf1 --- /dev/null +++ b/src/resources/organizations.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './organizations/index'; diff --git a/src/resources/projects.ts b/src/resources/projects.ts new file mode 100644 index 0000000..f9985fc --- /dev/null +++ b/src/resources/projects.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './projects/index'; diff --git a/src/resources/runners.ts b/src/resources/runners.ts new file mode 100644 index 0000000..003f18c --- /dev/null +++ b/src/resources/runners.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './runners/index'; diff --git a/src/resources/runners/configurations.ts b/src/resources/runners/configurations.ts new file mode 100644 index 0000000..451b34e --- /dev/null +++ b/src/resources/runners/configurations.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './configurations/index'; diff --git a/src/resources/users.ts b/src/resources/users.ts new file mode 100644 index 0000000..db908c7 --- /dev/null +++ b/src/resources/users.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './users/index'; From 716b94c4be5a42cfaf9f59fcdb9332b912113869 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 04:08:41 +0000 Subject: [PATCH 15/46] fix(internal): add mts file + crypto shim types (#58) --- scripts/build | 11 +++-------- src/internal/shims/crypto.node.d.mts | 1 + src/internal/shims/file.node.d.mts | 1 + 3 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 src/internal/shims/crypto.node.d.mts create mode 100644 src/internal/shims/file.node.d.mts diff --git a/scripts/build b/scripts/build index 7b100ad..047fe3d 100755 --- a/scripts/build +++ b/scripts/build @@ -28,20 +28,15 @@ node scripts/utils/make-dist-package-json.cjs > dist/package.json # build to .js/.mjs/.d.ts files npm exec tsc-multi -# we need to add exports = module.exports = Gitpod to index.js; -# No way to get that from index.ts because it would cause compile errors +# we need to patch index.js so that `new module.exports()` works for cjs backwards +# compat. No way to get that from index.ts because it would cause compile errors # when building .mjs node scripts/utils/fix-index-exports.cjs -# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts, -# it'll have TS errors on the default import. But if it resolves to -# index.d.mts the default import will work (even though both files have -# the same export default statement) -cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts mkdir -p dist/internal/shims -cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts new file mode 100644 index 0000000..5cc1963 --- /dev/null +++ b/src/internal/shims/crypto.node.d.mts @@ -0,0 +1 @@ +export { crypto } from './crypto.node.js'; diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts new file mode 100644 index 0000000..38cc9ff --- /dev/null +++ b/src/internal/shims/file.node.d.mts @@ -0,0 +1 @@ +export { File } from './file.node.js'; From 51d47fd93e6be04336019ec05c60841a5d25195c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 08:04:20 +0000 Subject: [PATCH 16/46] chore(internal): minor client file refactoring (#59) --- src/client.ts | 50 +++--------------------------------- src/internal/types.ts | 2 ++ src/internal/utils/log.ts | 30 +++++++++++++++++++++- src/internal/utils/values.ts | 8 ++++++ 4 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/client.ts b/src/client.ts index 8c0af2b..4371dfa 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,10 +1,12 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types'; -import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types'; +import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types'; import { uuid4 } from './internal/utils/uuid'; -import { validatePositiveInteger, isAbsoluteURL, hasOwn } from './internal/utils/values'; +import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; +import { type Logger, type LogLevel, parseLogLevel } from './internal/utils/log'; +export type { Logger, LogLevel } from './internal/utils/log'; import { castToError, isAbortError } from './internal/errors'; import type { APIResponseProps } from './internal/parse'; import { getPlatformHeaders } from './internal/detect-platform'; @@ -235,48 +237,6 @@ import { Users, } from './resources/users/users'; -const safeJSON = (text: string) => { - try { - return JSON.parse(text); - } catch (err) { - return undefined; - } -}; - -type LogFn = (message: string, ...rest: unknown[]) => void; -export type Logger = { - error: LogFn; - warn: LogFn; - info: LogFn; - debug: LogFn; -}; -export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; -const parseLogLevel = ( - maybeLevel: string | undefined, - sourceName: string, - client: Gitpod, -): LogLevel | undefined => { - if (!maybeLevel) { - return undefined; - } - const levels: Record = { - off: true, - error: true, - warn: true, - info: true, - debug: true, - }; - if (hasOwn(levels, maybeLevel)) { - return maybeLevel; - } - loggerFor(client).warn( - `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify( - Object.keys(levels), - )}`, - ); - return undefined; -}; - export interface ClientOptions { /** * Defaults to process.env['GITPOD_API_KEY']. @@ -350,8 +310,6 @@ export interface ClientOptions { logger?: Logger | undefined; } -type FinalizedRequestInit = RequestInit & { headers: Headers }; - /** * API Client for interfacing with the Gitpod API. */ diff --git a/src/internal/types.ts b/src/internal/types.ts index c3bce5a..d7928cd 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -5,6 +5,8 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; export type KeysEnum = { [P in keyof Required]: true }; +export type FinalizedRequestInit = RequestInit & { headers: Headers }; + type NotAny = [unknown] extends [T] ? never : T; /** diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index e446d4c..8fdf60d 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -1,9 +1,18 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import type { LogLevel, Logger } from '../../client'; +import { hasOwn } from './values'; import { type Gitpod } from '../../client'; import { RequestOptions } from '../request-options'; +type LogFn = (message: string, ...rest: unknown[]) => void; +export type Logger = { + error: LogFn; + warn: LogFn; + info: LogFn; + debug: LogFn; +}; +export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; + const levelNumbers = { off: 0, error: 200, @@ -12,6 +21,25 @@ const levelNumbers = { debug: 500, }; +export const parseLogLevel = ( + maybeLevel: string | undefined, + sourceName: string, + client: Gitpod, +): LogLevel | undefined => { + if (!maybeLevel) { + return undefined; + } + if (hasOwn(levelNumbers, maybeLevel)) { + return maybeLevel; + } + loggerFor(client).warn( + `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify( + Object.keys(levelNumbers), + )}`, + ); + return undefined; +}; + function noop() {} function makeLogFn(fnLevel: keyof Logger, logger: Logger | undefined, logLevel: LogLevel) { diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts index 86e3eda..43b0e39 100644 --- a/src/internal/utils/values.ts +++ b/src/internal/utils/values.ts @@ -92,3 +92,11 @@ export const maybeCoerceBoolean = (value: unknown): boolean | undefined => { } return coerceBoolean(value); }; + +export const safeJSON = (text: string) => { + try { + return JSON.parse(text); + } catch (err) { + return undefined; + } +}; From 0049aac07585fb4a1536ef6ff191b4ba5d5b9720 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 04:51:04 +0000 Subject: [PATCH 17/46] chore(exports): cleaner resource index imports (#60) --- src/resources.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/resources.ts diff --git a/src/resources.ts b/src/resources.ts new file mode 100644 index 0000000..b283d57 --- /dev/null +++ b/src/resources.ts @@ -0,0 +1 @@ +export * from './resources/index'; From a9df2c166e44d19ff8b374e5225d29971c72bb3e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 04:52:28 +0000 Subject: [PATCH 18/46] chore(exports): stop using path fallbacks (#61) --- scripts/utils/postprocess-files.cjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs index d16c864..deae575 100644 --- a/scripts/utils/postprocess-files.cjs +++ b/scripts/utils/postprocess-files.cjs @@ -50,14 +50,14 @@ async function postprocess() { if (entry.isDirectory() && entry.name !== 'src' && entry.name !== 'internal' && entry.name !== 'bin') { const subpath = './' + entry.name; newExports[subpath + '/*.mjs'] = { - default: [subpath + '/*.mjs', subpath + '/*/index.mjs'], + default: subpath + '/*.mjs', }; newExports[subpath + '/*.js'] = { - default: [subpath + '/*.js', subpath + '/*/index.js'], + default: subpath + '/*.js', }; newExports[subpath + '/*'] = { - import: [subpath + '/*.mjs', subpath + '/*/index.mjs'], - require: [subpath + '/*.js', subpath + '/*/index.js'], + import: subpath + '/*.mjs', + require: subpath + '/*.js', }; } else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) { const { name, ext } = path.parse(entry.name); From b79e1f2dd9348ab00466e4477af0fe08670354e4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 03:35:22 +0000 Subject: [PATCH 19/46] codegen metadata --- .stats.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.stats.yml b/.stats.yml index 2c4d8ac..e8f1d28 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,4 @@ configured_endpoints: 111 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3655d5ad0ac3e228c1519af70dbf3d0bfa3c47a2d06d4cac92a650da051b49a6.yml +openapi_spec_hash: 5dbb5577e6a7cae7db615b1b06c9d23e +config_hash: 719ad411c0ec7402a7a4c1f95515280c From e4008c3ab36557410e2124287eb9ab861e5d81d2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 03:42:03 +0000 Subject: [PATCH 20/46] chore(client): move misc public files to new `core/` directory, deprecate old paths (#62) --- src/api-promise.ts | 94 +- src/client.ts | 10 +- src/core/README.md | 3 + src/core/api-promise.ts | 92 ++ src/core/error.ts | 140 ++ src/core/pagination.ts | 1220 ++++++++++++++++ src/core/resource.ts | 11 + src/core/uploads.ts | 2 + src/error.ts | 142 +- src/index.ts | 8 +- src/internal/README.md | 3 + src/internal/decoders/jsonl.ts | 2 +- src/internal/decoders/line.ts | 2 +- src/internal/utils/base64.ts | 2 +- src/internal/utils/path.ts | 2 +- src/internal/utils/values.ts | 2 +- src/pagination.ts | 1222 +---------------- src/resource.ts | 13 +- src/resources/accounts.ts | 6 +- src/resources/editors.ts | 6 +- .../environments/automations/automations.ts | 4 +- .../environments/automations/services.ts | 6 +- .../automations/tasks/executions.ts | 6 +- .../environments/automations/tasks/tasks.ts | 6 +- src/resources/environments/classes.ts | 8 +- src/resources/environments/environments.ts | 6 +- src/resources/events.ts | 6 +- src/resources/groups.ts | 4 +- src/resources/identity.ts | 4 +- .../organizations/domain-verifications.ts | 10 +- src/resources/organizations/invites.ts | 4 +- src/resources/organizations/organizations.ts | 6 +- .../organizations/sso-configurations.ts | 6 +- src/resources/projects/policies.ts | 6 +- src/resources/projects/projects.ts | 6 +- .../runners/configurations/configurations.ts | 4 +- .../configurations/environment-classes.ts | 10 +- .../host-authentication-tokens.ts | 6 +- .../runners/configurations/schema.ts | 4 +- .../configurations/scm-integrations.ts | 6 +- src/resources/runners/policies.ts | 6 +- src/resources/runners/runners.ts | 6 +- src/resources/secrets.ts | 6 +- src/resources/shared.ts | 2 +- src/resources/users/pats.ts | 10 +- src/resources/users/users.ts | 4 +- src/uploads.ts | 4 +- tests/form.test.ts | 2 +- tests/index.test.ts | 2 +- tests/uploads.test.ts | 4 +- 50 files changed, 1589 insertions(+), 1557 deletions(-) create mode 100644 src/core/README.md create mode 100644 src/core/api-promise.ts create mode 100644 src/core/error.ts create mode 100644 src/core/pagination.ts create mode 100644 src/core/resource.ts create mode 100644 src/core/uploads.ts create mode 100644 src/internal/README.md diff --git a/src/api-promise.ts b/src/api-promise.ts index a7416b0..8c775ee 100644 --- a/src/api-promise.ts +++ b/src/api-promise.ts @@ -1,92 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { type Gitpod } from './client'; - -import { type PromiseOrValue } from './internal/types'; -import { APIResponseProps, defaultParseResponse } from './internal/parse'; - -/** - * A subclass of `Promise` providing additional helper methods - * for interacting with the SDK. - */ -export class APIPromise extends Promise { - private parsedPromise: Promise | undefined; - #client: Gitpod; - - constructor( - client: Gitpod, - private responsePromise: Promise, - private parseResponse: ( - client: Gitpod, - props: APIResponseProps, - ) => PromiseOrValue = defaultParseResponse, - ) { - super((resolve) => { - // this is maybe a bit weird but this has to be a no-op to not implicitly - // parse the response body; instead .then, .catch, .finally are overridden - // to parse the response - resolve(null as any); - }); - this.#client = client; - } - - _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { - return new APIPromise(this.#client, this.responsePromise, async (client, props) => - transform(await this.parseResponse(client, props), props), - ); - } - - /** - * Gets the raw `Response` instance instead of parsing the response - * data. - * - * If you want to parse the response body but still get the `Response` - * instance, you can use {@link withResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - asResponse(): Promise { - return this.responsePromise.then((p) => p.response); - } - - /** - * Gets the parsed response data and the raw `Response` instance. - * - * If you just want to get the raw `Response` instance without parsing it, - * you can use {@link asResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - async withResponse(): Promise<{ data: T; response: Response }> { - const [data, response] = await Promise.all([this.parse(), this.asResponse()]); - return { data, response }; - } - - private parse(): Promise { - if (!this.parsedPromise) { - this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data)); - } - return this.parsedPromise; - } - - override then( - onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null, - ): Promise { - return this.parse().then(onfulfilled, onrejected); - } - - override catch( - onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null, - ): Promise { - return this.parse().catch(onrejected); - } - - override finally(onfinally?: (() => void) | undefined | null): Promise { - return this.parse().finally(onfinally); - } -} +/** @deprecated Import from ./core/api-promise instead */ +export * from './core/api-promise'; diff --git a/src/client.ts b/src/client.ts index 4371dfa..ef0b007 100644 --- a/src/client.ts +++ b/src/client.ts @@ -13,8 +13,8 @@ import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; import * as Opts from './internal/request-options'; import { VERSION } from './version'; -import * as Errors from './error'; -import * as Pagination from './pagination'; +import * as Errors from './core/error'; +import * as Pagination from './core/pagination'; import { AbstractPage, type DomainVerificationsPageParams, @@ -57,10 +57,10 @@ import { TasksPageResponse, type TokensPageParams, TokensPageResponse, -} from './pagination'; -import * as Uploads from './uploads'; +} from './core/pagination'; +import * as Uploads from './core/uploads'; import * as API from './resources/index'; -import { APIPromise } from './api-promise'; +import { APIPromise } from './core/api-promise'; import { type Fetch } from './internal/builtin-types'; import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers'; import { FinalRequestOptions, RequestOptions } from './internal/request-options'; diff --git a/src/core/README.md b/src/core/README.md new file mode 100644 index 0000000..485fce8 --- /dev/null +++ b/src/core/README.md @@ -0,0 +1,3 @@ +# `core` + +This directory holds public modules implementing non-resource-specific SDK functionality. diff --git a/src/core/api-promise.ts b/src/core/api-promise.ts new file mode 100644 index 0000000..639a545 --- /dev/null +++ b/src/core/api-promise.ts @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { type Gitpod } from '../client'; + +import { type PromiseOrValue } from '../internal/types'; +import { APIResponseProps, defaultParseResponse } from '../internal/parse'; + +/** + * A subclass of `Promise` providing additional helper methods + * for interacting with the SDK. + */ +export class APIPromise extends Promise { + private parsedPromise: Promise | undefined; + #client: Gitpod; + + constructor( + client: Gitpod, + private responsePromise: Promise, + private parseResponse: ( + client: Gitpod, + props: APIResponseProps, + ) => PromiseOrValue = defaultParseResponse, + ) { + super((resolve) => { + // this is maybe a bit weird but this has to be a no-op to not implicitly + // parse the response body; instead .then, .catch, .finally are overridden + // to parse the response + resolve(null as any); + }); + this.#client = client; + } + + _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { + return new APIPromise(this.#client, this.responsePromise, async (client, props) => + transform(await this.parseResponse(client, props), props), + ); + } + + /** + * Gets the raw `Response` instance instead of parsing the response + * data. + * + * If you want to parse the response body but still get the `Response` + * instance, you can use {@link withResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + asResponse(): Promise { + return this.responsePromise.then((p) => p.response); + } + + /** + * Gets the parsed response data and the raw `Response` instance. + * + * If you just want to get the raw `Response` instance without parsing it, + * you can use {@link asResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + async withResponse(): Promise<{ data: T; response: Response }> { + const [data, response] = await Promise.all([this.parse(), this.asResponse()]); + return { data, response }; + } + + private parse(): Promise { + if (!this.parsedPromise) { + this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data)); + } + return this.parsedPromise; + } + + override then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, + onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null, + ): Promise { + return this.parse().then(onfulfilled, onrejected); + } + + override catch( + onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null, + ): Promise { + return this.parse().catch(onrejected); + } + + override finally(onfinally?: (() => void) | undefined | null): Promise { + return this.parse().finally(onfinally); + } +} diff --git a/src/core/error.ts b/src/core/error.ts new file mode 100644 index 0000000..1b22334 --- /dev/null +++ b/src/core/error.ts @@ -0,0 +1,140 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { castToError } from '../internal/errors'; +import * as Shared from '../resources/shared'; + +export class GitpodError extends Error {} + +export class APIError< + TStatus extends number | undefined = number | undefined, + THeaders extends Headers | undefined = Headers | undefined, + TError extends Object | undefined = Object | undefined, +> extends GitpodError { + /** HTTP status for the response that caused the error */ + readonly status: TStatus; + /** HTTP headers for the response that caused the error */ + readonly headers: THeaders; + /** JSON body of the response that caused the error */ + readonly error: TError; + + /** + * The status code, which should be an enum value of + * [google.rpc.Code][google.rpc.Code]. + */ + readonly code?: Shared.ErrorCode | undefined; + + constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { + super(`${APIError.makeMessage(status, error, message)}`); + this.status = status; + this.headers = headers; + this.error = error; + + const data = error as Record; + this.code = data?.['code']; + } + + private static makeMessage(status: number | undefined, error: any, message: string | undefined) { + const msg = + error?.message ? + typeof error.message === 'string' ? + error.message + : JSON.stringify(error.message) + : error ? JSON.stringify(error) + : message; + + if (status && msg) { + return `${status} ${msg}`; + } + if (status) { + return `${status} status code (no body)`; + } + if (msg) { + return msg; + } + return '(no status code or body)'; + } + + static generate( + status: number | undefined, + errorResponse: Object | undefined, + message: string | undefined, + headers: Headers | undefined, + ): APIError { + if (!status || !headers) { + return new APIConnectionError({ message, cause: castToError(errorResponse) }); + } + + const error = errorResponse as Record; + + if (status === 400) { + return new BadRequestError(status, error, message, headers); + } + + if (status === 401) { + return new AuthenticationError(status, error, message, headers); + } + + if (status === 403) { + return new PermissionDeniedError(status, error, message, headers); + } + + if (status === 404) { + return new NotFoundError(status, error, message, headers); + } + + if (status === 409) { + return new ConflictError(status, error, message, headers); + } + + if (status === 422) { + return new UnprocessableEntityError(status, error, message, headers); + } + + if (status === 429) { + return new RateLimitError(status, error, message, headers); + } + + if (status >= 500) { + return new InternalServerError(status, error, message, headers); + } + + return new APIError(status, error, message, headers); + } +} + +export class APIUserAbortError extends APIError { + constructor({ message }: { message?: string } = {}) { + super(undefined, undefined, message || 'Request was aborted.', undefined); + } +} + +export class APIConnectionError extends APIError { + constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { + super(undefined, undefined, message || 'Connection error.', undefined); + // in some environments the 'cause' property is already declared + // @ts-ignore + if (cause) this.cause = cause; + } +} + +export class APIConnectionTimeoutError extends APIConnectionError { + constructor({ message }: { message?: string } = {}) { + super({ message: message ?? 'Request timed out.' }); + } +} + +export class BadRequestError extends APIError<400, Headers> {} + +export class AuthenticationError extends APIError<401, Headers> {} + +export class PermissionDeniedError extends APIError<403, Headers> {} + +export class NotFoundError extends APIError<404, Headers> {} + +export class ConflictError extends APIError<409, Headers> {} + +export class UnprocessableEntityError extends APIError<422, Headers> {} + +export class RateLimitError extends APIError<429, Headers> {} + +export class InternalServerError extends APIError {} diff --git a/src/core/pagination.ts b/src/core/pagination.ts new file mode 100644 index 0000000..5ae7b97 --- /dev/null +++ b/src/core/pagination.ts @@ -0,0 +1,1220 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { GitpodError } from './error'; +import { FinalRequestOptions } from '../internal/request-options'; +import { defaultParseResponse } from '../internal/parse'; +import { type Gitpod } from '../client'; +import { APIPromise } from './api-promise'; +import { type APIResponseProps } from '../internal/parse'; +import { maybeObj } from '../internal/utils/values'; + +export type PageRequestOptions = Pick; + +export abstract class AbstractPage implements AsyncIterable { + #client: Gitpod; + protected options: FinalRequestOptions; + + protected response: Response; + protected body: unknown; + + constructor(client: Gitpod, response: Response, body: unknown, options: FinalRequestOptions) { + this.#client = client; + this.options = options; + this.response = response; + this.body = body; + } + + abstract nextPageRequestOptions(): PageRequestOptions | null; + + abstract getPaginatedItems(): Item[]; + + hasNextPage(): boolean { + const items = this.getPaginatedItems(); + if (!items.length) return false; + return this.nextPageRequestOptions() != null; + } + + async getNextPage(): Promise { + const nextOptions = this.nextPageRequestOptions(); + if (!nextOptions) { + throw new GitpodError( + 'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.', + ); + } + + return await this.#client.requestAPIList(this.constructor as any, nextOptions); + } + + async *iterPages(): AsyncGenerator { + let page: this = this; + yield page; + while (page.hasNextPage()) { + page = await page.getNextPage(); + yield page; + } + } + + async *[Symbol.asyncIterator](): AsyncGenerator { + for await (const page of this.iterPages()) { + for (const item of page.getPaginatedItems()) { + yield item; + } + } + } +} + +/** + * This subclass of Promise will resolve to an instantiated Page once the request completes. + * + * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ +export class PagePromise< + PageClass extends AbstractPage, + Item = ReturnType[number], + > + extends APIPromise + implements AsyncIterable +{ + constructor( + client: Gitpod, + request: Promise, + Page: new (...args: ConstructorParameters) => PageClass, + ) { + super( + client, + request, + async (client, props) => + new Page(client, props.response, await defaultParseResponse(client, props), props.options), + ); + } + + /** + * Allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ + async *[Symbol.asyncIterator]() { + const page = await this; + for await (const item of page) { + yield item; + } + } +} + +export interface DomainVerificationsPageResponse { + domainVerifications: Array; + + pagination: DomainVerificationsPageResponse.Pagination; +} + +export namespace DomainVerificationsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface DomainVerificationsPageParams { + pageSize?: number; + + token?: string; +} + +export class DomainVerificationsPage + extends AbstractPage + implements DomainVerificationsPageResponse +{ + domainVerifications: Array; + + pagination: DomainVerificationsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: DomainVerificationsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.domainVerifications = body.domainVerifications || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.domainVerifications ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface EditorsPageResponse { + editors: Array; + + pagination: EditorsPageResponse.Pagination; +} + +export namespace EditorsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface EditorsPageParams { + pageSize?: number; + + token?: string; +} + +export class EditorsPage extends AbstractPage implements EditorsPageResponse { + editors: Array; + + pagination: EditorsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: EditorsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.editors = body.editors || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.editors ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface EntriesPageResponse { + entries: Array; + + pagination: EntriesPageResponse.Pagination; +} + +export namespace EntriesPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface EntriesPageParams { + pageSize?: number; + + token?: string; +} + +export class EntriesPage extends AbstractPage implements EntriesPageResponse { + entries: Array; + + pagination: EntriesPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: EntriesPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.entries = body.entries || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.entries ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface EnvironmentClassesPageResponse { + environmentClasses: Array; + + pagination: EnvironmentClassesPageResponse.Pagination; +} + +export namespace EnvironmentClassesPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface EnvironmentClassesPageParams { + pageSize?: number; + + token?: string; +} + +export class EnvironmentClassesPage + extends AbstractPage + implements EnvironmentClassesPageResponse +{ + environmentClasses: Array; + + pagination: EnvironmentClassesPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: EnvironmentClassesPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.environmentClasses = body.environmentClasses || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.environmentClasses ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface EnvironmentsPageResponse { + environments: Array; + + pagination: EnvironmentsPageResponse.Pagination; +} + +export namespace EnvironmentsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface EnvironmentsPageParams { + pageSize?: number; + + token?: string; +} + +export class EnvironmentsPage extends AbstractPage implements EnvironmentsPageResponse { + environments: Array; + + pagination: EnvironmentsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: EnvironmentsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.environments = body.environments || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.environments ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface GroupsPageResponse { + groups: Array; + + pagination: GroupsPageResponse.Pagination; +} + +export namespace GroupsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface GroupsPageParams { + pageSize?: number; + + token?: string; +} + +export class GroupsPage extends AbstractPage implements GroupsPageResponse { + groups: Array; + + pagination: GroupsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: GroupsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.groups = body.groups || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.groups ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface IntegrationsPageResponse { + integrations: Array; + + pagination: IntegrationsPageResponse.Pagination; +} + +export namespace IntegrationsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface IntegrationsPageParams { + pageSize?: number; + + token?: string; +} + +export class IntegrationsPage extends AbstractPage implements IntegrationsPageResponse { + integrations: Array; + + pagination: IntegrationsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: IntegrationsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.integrations = body.integrations || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.integrations ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface LoginProvidersPageResponse { + loginProviders: Array; + + pagination: LoginProvidersPageResponse.Pagination; +} + +export namespace LoginProvidersPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface LoginProvidersPageParams { + pageSize?: number; + + token?: string; +} + +export class LoginProvidersPage extends AbstractPage implements LoginProvidersPageResponse { + loginProviders: Array; + + pagination: LoginProvidersPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: LoginProvidersPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.loginProviders = body.loginProviders || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.loginProviders ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface MembersPageResponse { + members: Array; + + pagination: MembersPageResponse.Pagination; +} + +export namespace MembersPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface MembersPageParams { + pageSize?: number; + + token?: string; +} + +export class MembersPage extends AbstractPage implements MembersPageResponse { + members: Array; + + pagination: MembersPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: MembersPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.members = body.members || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.members ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface OrganizationsPageResponse { + organizations: Array; + + pagination: OrganizationsPageResponse.Pagination; +} + +export namespace OrganizationsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface OrganizationsPageParams { + pageSize?: number; + + token?: string; +} + +export class OrganizationsPage extends AbstractPage implements OrganizationsPageResponse { + organizations: Array; + + pagination: OrganizationsPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: OrganizationsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.organizations = body.organizations || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.organizations ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface PersonalAccessTokensPageResponse { + pagination: PersonalAccessTokensPageResponse.Pagination; + + personalAccessTokens: Array; +} + +export namespace PersonalAccessTokensPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface PersonalAccessTokensPageParams { + pageSize?: number; + + token?: string; +} + +export class PersonalAccessTokensPage + extends AbstractPage + implements PersonalAccessTokensPageResponse +{ + pagination: PersonalAccessTokensPageResponse.Pagination; + + personalAccessTokens: Array; + + constructor( + client: Gitpod, + response: Response, + body: PersonalAccessTokensPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.personalAccessTokens = body.personalAccessTokens || []; + } + + getPaginatedItems(): Item[] { + return this.personalAccessTokens ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface PoliciesPageResponse { + pagination: PoliciesPageResponse.Pagination; + + policies: Array; +} + +export namespace PoliciesPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface PoliciesPageParams { + pageSize?: number; + + token?: string; +} + +export class PoliciesPage extends AbstractPage implements PoliciesPageResponse { + pagination: PoliciesPageResponse.Pagination; + + policies: Array; + + constructor( + client: Gitpod, + response: Response, + body: PoliciesPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.policies = body.policies || []; + } + + getPaginatedItems(): Item[] { + return this.policies ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface ProjectsPageResponse { + pagination: ProjectsPageResponse.Pagination; + + projects: Array; +} + +export namespace ProjectsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface ProjectsPageParams { + pageSize?: number; + + token?: string; +} + +export class ProjectsPage extends AbstractPage implements ProjectsPageResponse { + pagination: ProjectsPageResponse.Pagination; + + projects: Array; + + constructor( + client: Gitpod, + response: Response, + body: ProjectsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.projects = body.projects || []; + } + + getPaginatedItems(): Item[] { + return this.projects ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface RunnersPageResponse { + pagination: RunnersPageResponse.Pagination; + + runners: Array; +} + +export namespace RunnersPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface RunnersPageParams { + pageSize?: number; + + token?: string; +} + +export class RunnersPage extends AbstractPage implements RunnersPageResponse { + pagination: RunnersPageResponse.Pagination; + + runners: Array; + + constructor( + client: Gitpod, + response: Response, + body: RunnersPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.runners = body.runners || []; + } + + getPaginatedItems(): Item[] { + return this.runners ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface SecretsPageResponse { + pagination: SecretsPageResponse.Pagination; + + secrets: Array; +} + +export namespace SecretsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface SecretsPageParams { + pageSize?: number; + + token?: string; +} + +export class SecretsPage extends AbstractPage implements SecretsPageResponse { + pagination: SecretsPageResponse.Pagination; + + secrets: Array; + + constructor( + client: Gitpod, + response: Response, + body: SecretsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.secrets = body.secrets || []; + } + + getPaginatedItems(): Item[] { + return this.secrets ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface ServicesPageResponse { + pagination: ServicesPageResponse.Pagination; + + services: Array; +} + +export namespace ServicesPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface ServicesPageParams { + pageSize?: number; + + token?: string; +} + +export class ServicesPage extends AbstractPage implements ServicesPageResponse { + pagination: ServicesPageResponse.Pagination; + + services: Array; + + constructor( + client: Gitpod, + response: Response, + body: ServicesPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.services = body.services || []; + } + + getPaginatedItems(): Item[] { + return this.services ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface SSOConfigurationsPageResponse { + pagination: SSOConfigurationsPageResponse.Pagination; + + ssoConfigurations: Array; +} + +export namespace SSOConfigurationsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface SSOConfigurationsPageParams { + pageSize?: number; + + token?: string; +} + +export class SSOConfigurationsPage + extends AbstractPage + implements SSOConfigurationsPageResponse +{ + pagination: SSOConfigurationsPageResponse.Pagination; + + ssoConfigurations: Array; + + constructor( + client: Gitpod, + response: Response, + body: SSOConfigurationsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.ssoConfigurations = body.ssoConfigurations || []; + } + + getPaginatedItems(): Item[] { + return this.ssoConfigurations ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface TaskExecutionsPageResponse { + pagination: TaskExecutionsPageResponse.Pagination; + + taskExecutions: Array; +} + +export namespace TaskExecutionsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface TaskExecutionsPageParams { + pageSize?: number; + + token?: string; +} + +export class TaskExecutionsPage extends AbstractPage implements TaskExecutionsPageResponse { + pagination: TaskExecutionsPageResponse.Pagination; + + taskExecutions: Array; + + constructor( + client: Gitpod, + response: Response, + body: TaskExecutionsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.taskExecutions = body.taskExecutions || []; + } + + getPaginatedItems(): Item[] { + return this.taskExecutions ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface TasksPageResponse { + pagination: TasksPageResponse.Pagination; + + tasks: Array; +} + +export namespace TasksPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface TasksPageParams { + pageSize?: number; + + token?: string; +} + +export class TasksPage extends AbstractPage implements TasksPageResponse { + pagination: TasksPageResponse.Pagination; + + tasks: Array; + + constructor( + client: Gitpod, + response: Response, + body: TasksPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.tasks = body.tasks || []; + } + + getPaginatedItems(): Item[] { + return this.tasks ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + +export interface TokensPageResponse { + pagination: TokensPageResponse.Pagination; + + tokens: Array; +} + +export namespace TokensPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface TokensPageParams { + pageSize?: number; + + token?: string; +} + +export class TokensPage extends AbstractPage implements TokensPageResponse { + pagination: TokensPageResponse.Pagination; + + tokens: Array; + + constructor( + client: Gitpod, + response: Response, + body: TokensPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.tokens = body.tokens || []; + } + + getPaginatedItems(): Item[] { + return this.tokens ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} diff --git a/src/core/resource.ts b/src/core/resource.ts new file mode 100644 index 0000000..c73b82d --- /dev/null +++ b/src/core/resource.ts @@ -0,0 +1,11 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import type { Gitpod } from '../client'; + +export class APIResource { + protected _client: Gitpod; + + constructor(client: Gitpod) { + this._client = client; + } +} diff --git a/src/core/uploads.ts b/src/core/uploads.ts new file mode 100644 index 0000000..2882ca6 --- /dev/null +++ b/src/core/uploads.ts @@ -0,0 +1,2 @@ +export { type Uploadable } from '../internal/uploads'; +export { toFile, type ToFileInput } from '../internal/to-file'; diff --git a/src/error.ts b/src/error.ts index 67145c6..fc55f46 100644 --- a/src/error.ts +++ b/src/error.ts @@ -1,140 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { castToError } from './internal/errors'; -import * as Shared from './resources/shared'; - -export class GitpodError extends Error {} - -export class APIError< - TStatus extends number | undefined = number | undefined, - THeaders extends Headers | undefined = Headers | undefined, - TError extends Object | undefined = Object | undefined, -> extends GitpodError { - /** HTTP status for the response that caused the error */ - readonly status: TStatus; - /** HTTP headers for the response that caused the error */ - readonly headers: THeaders; - /** JSON body of the response that caused the error */ - readonly error: TError; - - /** - * The status code, which should be an enum value of - * [google.rpc.Code][google.rpc.Code]. - */ - readonly code?: Shared.ErrorCode | undefined; - - constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { - super(`${APIError.makeMessage(status, error, message)}`); - this.status = status; - this.headers = headers; - this.error = error; - - const data = error as Record; - this.code = data?.['code']; - } - - private static makeMessage(status: number | undefined, error: any, message: string | undefined) { - const msg = - error?.message ? - typeof error.message === 'string' ? - error.message - : JSON.stringify(error.message) - : error ? JSON.stringify(error) - : message; - - if (status && msg) { - return `${status} ${msg}`; - } - if (status) { - return `${status} status code (no body)`; - } - if (msg) { - return msg; - } - return '(no status code or body)'; - } - - static generate( - status: number | undefined, - errorResponse: Object | undefined, - message: string | undefined, - headers: Headers | undefined, - ): APIError { - if (!status || !headers) { - return new APIConnectionError({ message, cause: castToError(errorResponse) }); - } - - const error = errorResponse as Record; - - if (status === 400) { - return new BadRequestError(status, error, message, headers); - } - - if (status === 401) { - return new AuthenticationError(status, error, message, headers); - } - - if (status === 403) { - return new PermissionDeniedError(status, error, message, headers); - } - - if (status === 404) { - return new NotFoundError(status, error, message, headers); - } - - if (status === 409) { - return new ConflictError(status, error, message, headers); - } - - if (status === 422) { - return new UnprocessableEntityError(status, error, message, headers); - } - - if (status === 429) { - return new RateLimitError(status, error, message, headers); - } - - if (status >= 500) { - return new InternalServerError(status, error, message, headers); - } - - return new APIError(status, error, message, headers); - } -} - -export class APIUserAbortError extends APIError { - constructor({ message }: { message?: string } = {}) { - super(undefined, undefined, message || 'Request was aborted.', undefined); - } -} - -export class APIConnectionError extends APIError { - constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { - super(undefined, undefined, message || 'Connection error.', undefined); - // in some environments the 'cause' property is already declared - // @ts-ignore - if (cause) this.cause = cause; - } -} - -export class APIConnectionTimeoutError extends APIConnectionError { - constructor({ message }: { message?: string } = {}) { - super({ message: message ?? 'Request timed out.' }); - } -} - -export class BadRequestError extends APIError<400, Headers> {} - -export class AuthenticationError extends APIError<401, Headers> {} - -export class PermissionDeniedError extends APIError<403, Headers> {} - -export class NotFoundError extends APIError<404, Headers> {} - -export class ConflictError extends APIError<409, Headers> {} - -export class UnprocessableEntityError extends APIError<422, Headers> {} - -export class RateLimitError extends APIError<429, Headers> {} - -export class InternalServerError extends APIError {} +/** @deprecated Import from ./core/error instead */ +export * from './core/error'; diff --git a/src/index.ts b/src/index.ts index 2b3917a..0eaf4c8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,10 +2,10 @@ export { Gitpod as default } from './client'; -export { type Uploadable, toFile } from './uploads'; -export { APIPromise } from './api-promise'; +export { type Uploadable, toFile } from './core/uploads'; +export { APIPromise } from './core/api-promise'; export { Gitpod, type ClientOptions } from './client'; -export { PagePromise } from './pagination'; +export { PagePromise } from './core/pagination'; export { GitpodError, APIError, @@ -20,4 +20,4 @@ export { InternalServerError, PermissionDeniedError, UnprocessableEntityError, -} from './error'; +} from './core/error'; diff --git a/src/internal/README.md b/src/internal/README.md new file mode 100644 index 0000000..3ef5a25 --- /dev/null +++ b/src/internal/README.md @@ -0,0 +1,3 @@ +# `internal` + +The modules in this directory are not importable outside this package and will change between releases. diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts index cb40d92..79ec5f8 100644 --- a/src/internal/decoders/jsonl.ts +++ b/src/internal/decoders/jsonl.ts @@ -1,4 +1,4 @@ -import { GitpodError } from '../../error'; +import { GitpodError } from '../../core/error'; import { ReadableStreamToAsyncIterable } from '../shims'; import { LineDecoder, type Bytes } from './line'; diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index 0295286..a4c237f 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -1,4 +1,4 @@ -import { GitpodError } from '../../error'; +import { GitpodError } from '../../core/error'; export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts index 3b077b3..50d616c 100644 --- a/src/internal/utils/base64.ts +++ b/src/internal/utils/base64.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { GitpodError } from '../../error'; +import { GitpodError } from '../../core/error'; export const toBase64 = (data: string | Uint8Array | null | undefined): string => { if (!data) return ''; diff --git a/src/internal/utils/path.ts b/src/internal/utils/path.ts index 0115b07..56154a2 100644 --- a/src/internal/utils/path.ts +++ b/src/internal/utils/path.ts @@ -1,4 +1,4 @@ -import { GitpodError } from '../../error'; +import { GitpodError } from '../../core/error'; /** * Percent-encode everything that isn't safe to have in a path without encoding safe chars. diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts index 43b0e39..d0e9c61 100644 --- a/src/internal/utils/values.ts +++ b/src/internal/utils/values.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { GitpodError } from '../../error'; +import { GitpodError } from '../../core/error'; // https://url.spec.whatwg.org/#url-scheme-string const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; diff --git a/src/pagination.ts b/src/pagination.ts index 7bacc0a..90bf015 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -1,1220 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { GitpodError } from './error'; -import { FinalRequestOptions } from './internal/request-options'; -import { defaultParseResponse } from './internal/parse'; -import { APIPromise } from './api-promise'; -import { type Gitpod } from './client'; -import { type APIResponseProps } from './internal/parse'; -import { maybeObj } from './internal/utils/values'; - -export type PageRequestOptions = Pick; - -export abstract class AbstractPage implements AsyncIterable { - #client: Gitpod; - protected options: FinalRequestOptions; - - protected response: Response; - protected body: unknown; - - constructor(client: Gitpod, response: Response, body: unknown, options: FinalRequestOptions) { - this.#client = client; - this.options = options; - this.response = response; - this.body = body; - } - - abstract nextPageRequestOptions(): PageRequestOptions | null; - - abstract getPaginatedItems(): Item[]; - - hasNextPage(): boolean { - const items = this.getPaginatedItems(); - if (!items.length) return false; - return this.nextPageRequestOptions() != null; - } - - async getNextPage(): Promise { - const nextOptions = this.nextPageRequestOptions(); - if (!nextOptions) { - throw new GitpodError( - 'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.', - ); - } - - return await this.#client.requestAPIList(this.constructor as any, nextOptions); - } - - async *iterPages(): AsyncGenerator { - let page: this = this; - yield page; - while (page.hasNextPage()) { - page = await page.getNextPage(); - yield page; - } - } - - async *[Symbol.asyncIterator](): AsyncGenerator { - for await (const page of this.iterPages()) { - for (const item of page.getPaginatedItems()) { - yield item; - } - } - } -} - -/** - * This subclass of Promise will resolve to an instantiated Page once the request completes. - * - * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ -export class PagePromise< - PageClass extends AbstractPage, - Item = ReturnType[number], - > - extends APIPromise - implements AsyncIterable -{ - constructor( - client: Gitpod, - request: Promise, - Page: new (...args: ConstructorParameters) => PageClass, - ) { - super( - client, - request, - async (client, props) => - new Page(client, props.response, await defaultParseResponse(client, props), props.options), - ); - } - - /** - * Allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ - async *[Symbol.asyncIterator]() { - const page = await this; - for await (const item of page) { - yield item; - } - } -} - -export interface DomainVerificationsPageResponse { - domainVerifications: Array; - - pagination: DomainVerificationsPageResponse.Pagination; -} - -export namespace DomainVerificationsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface DomainVerificationsPageParams { - pageSize?: number; - - token?: string; -} - -export class DomainVerificationsPage - extends AbstractPage - implements DomainVerificationsPageResponse -{ - domainVerifications: Array; - - pagination: DomainVerificationsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: DomainVerificationsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.domainVerifications = body.domainVerifications || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.domainVerifications ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface EditorsPageResponse { - editors: Array; - - pagination: EditorsPageResponse.Pagination; -} - -export namespace EditorsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface EditorsPageParams { - pageSize?: number; - - token?: string; -} - -export class EditorsPage extends AbstractPage implements EditorsPageResponse { - editors: Array; - - pagination: EditorsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: EditorsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.editors = body.editors || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.editors ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface EntriesPageResponse { - entries: Array; - - pagination: EntriesPageResponse.Pagination; -} - -export namespace EntriesPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface EntriesPageParams { - pageSize?: number; - - token?: string; -} - -export class EntriesPage extends AbstractPage implements EntriesPageResponse { - entries: Array; - - pagination: EntriesPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: EntriesPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.entries = body.entries || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.entries ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface EnvironmentClassesPageResponse { - environmentClasses: Array; - - pagination: EnvironmentClassesPageResponse.Pagination; -} - -export namespace EnvironmentClassesPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface EnvironmentClassesPageParams { - pageSize?: number; - - token?: string; -} - -export class EnvironmentClassesPage - extends AbstractPage - implements EnvironmentClassesPageResponse -{ - environmentClasses: Array; - - pagination: EnvironmentClassesPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: EnvironmentClassesPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.environmentClasses = body.environmentClasses || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.environmentClasses ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface EnvironmentsPageResponse { - environments: Array; - - pagination: EnvironmentsPageResponse.Pagination; -} - -export namespace EnvironmentsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface EnvironmentsPageParams { - pageSize?: number; - - token?: string; -} - -export class EnvironmentsPage extends AbstractPage implements EnvironmentsPageResponse { - environments: Array; - - pagination: EnvironmentsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: EnvironmentsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.environments = body.environments || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.environments ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface GroupsPageResponse { - groups: Array; - - pagination: GroupsPageResponse.Pagination; -} - -export namespace GroupsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface GroupsPageParams { - pageSize?: number; - - token?: string; -} - -export class GroupsPage extends AbstractPage implements GroupsPageResponse { - groups: Array; - - pagination: GroupsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: GroupsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.groups = body.groups || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.groups ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface IntegrationsPageResponse { - integrations: Array; - - pagination: IntegrationsPageResponse.Pagination; -} - -export namespace IntegrationsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface IntegrationsPageParams { - pageSize?: number; - - token?: string; -} - -export class IntegrationsPage extends AbstractPage implements IntegrationsPageResponse { - integrations: Array; - - pagination: IntegrationsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: IntegrationsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.integrations = body.integrations || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.integrations ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface LoginProvidersPageResponse { - loginProviders: Array; - - pagination: LoginProvidersPageResponse.Pagination; -} - -export namespace LoginProvidersPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface LoginProvidersPageParams { - pageSize?: number; - - token?: string; -} - -export class LoginProvidersPage extends AbstractPage implements LoginProvidersPageResponse { - loginProviders: Array; - - pagination: LoginProvidersPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: LoginProvidersPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.loginProviders = body.loginProviders || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.loginProviders ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface MembersPageResponse { - members: Array; - - pagination: MembersPageResponse.Pagination; -} - -export namespace MembersPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface MembersPageParams { - pageSize?: number; - - token?: string; -} - -export class MembersPage extends AbstractPage implements MembersPageResponse { - members: Array; - - pagination: MembersPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: MembersPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.members = body.members || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.members ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface OrganizationsPageResponse { - organizations: Array; - - pagination: OrganizationsPageResponse.Pagination; -} - -export namespace OrganizationsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface OrganizationsPageParams { - pageSize?: number; - - token?: string; -} - -export class OrganizationsPage extends AbstractPage implements OrganizationsPageResponse { - organizations: Array; - - pagination: OrganizationsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: OrganizationsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.organizations = body.organizations || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.organizations ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface PersonalAccessTokensPageResponse { - pagination: PersonalAccessTokensPageResponse.Pagination; - - personalAccessTokens: Array; -} - -export namespace PersonalAccessTokensPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface PersonalAccessTokensPageParams { - pageSize?: number; - - token?: string; -} - -export class PersonalAccessTokensPage - extends AbstractPage - implements PersonalAccessTokensPageResponse -{ - pagination: PersonalAccessTokensPageResponse.Pagination; - - personalAccessTokens: Array; - - constructor( - client: Gitpod, - response: Response, - body: PersonalAccessTokensPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.personalAccessTokens = body.personalAccessTokens || []; - } - - getPaginatedItems(): Item[] { - return this.personalAccessTokens ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface PoliciesPageResponse { - pagination: PoliciesPageResponse.Pagination; - - policies: Array; -} - -export namespace PoliciesPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface PoliciesPageParams { - pageSize?: number; - - token?: string; -} - -export class PoliciesPage extends AbstractPage implements PoliciesPageResponse { - pagination: PoliciesPageResponse.Pagination; - - policies: Array; - - constructor( - client: Gitpod, - response: Response, - body: PoliciesPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.policies = body.policies || []; - } - - getPaginatedItems(): Item[] { - return this.policies ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface ProjectsPageResponse { - pagination: ProjectsPageResponse.Pagination; - - projects: Array; -} - -export namespace ProjectsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface ProjectsPageParams { - pageSize?: number; - - token?: string; -} - -export class ProjectsPage extends AbstractPage implements ProjectsPageResponse { - pagination: ProjectsPageResponse.Pagination; - - projects: Array; - - constructor( - client: Gitpod, - response: Response, - body: ProjectsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.projects = body.projects || []; - } - - getPaginatedItems(): Item[] { - return this.projects ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface RunnersPageResponse { - pagination: RunnersPageResponse.Pagination; - - runners: Array; -} - -export namespace RunnersPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface RunnersPageParams { - pageSize?: number; - - token?: string; -} - -export class RunnersPage extends AbstractPage implements RunnersPageResponse { - pagination: RunnersPageResponse.Pagination; - - runners: Array; - - constructor( - client: Gitpod, - response: Response, - body: RunnersPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.runners = body.runners || []; - } - - getPaginatedItems(): Item[] { - return this.runners ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface SecretsPageResponse { - pagination: SecretsPageResponse.Pagination; - - secrets: Array; -} - -export namespace SecretsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface SecretsPageParams { - pageSize?: number; - - token?: string; -} - -export class SecretsPage extends AbstractPage implements SecretsPageResponse { - pagination: SecretsPageResponse.Pagination; - - secrets: Array; - - constructor( - client: Gitpod, - response: Response, - body: SecretsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.secrets = body.secrets || []; - } - - getPaginatedItems(): Item[] { - return this.secrets ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface ServicesPageResponse { - pagination: ServicesPageResponse.Pagination; - - services: Array; -} - -export namespace ServicesPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface ServicesPageParams { - pageSize?: number; - - token?: string; -} - -export class ServicesPage extends AbstractPage implements ServicesPageResponse { - pagination: ServicesPageResponse.Pagination; - - services: Array; - - constructor( - client: Gitpod, - response: Response, - body: ServicesPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.services = body.services || []; - } - - getPaginatedItems(): Item[] { - return this.services ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface SSOConfigurationsPageResponse { - pagination: SSOConfigurationsPageResponse.Pagination; - - ssoConfigurations: Array; -} - -export namespace SSOConfigurationsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface SSOConfigurationsPageParams { - pageSize?: number; - - token?: string; -} - -export class SSOConfigurationsPage - extends AbstractPage - implements SSOConfigurationsPageResponse -{ - pagination: SSOConfigurationsPageResponse.Pagination; - - ssoConfigurations: Array; - - constructor( - client: Gitpod, - response: Response, - body: SSOConfigurationsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.ssoConfigurations = body.ssoConfigurations || []; - } - - getPaginatedItems(): Item[] { - return this.ssoConfigurations ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface TaskExecutionsPageResponse { - pagination: TaskExecutionsPageResponse.Pagination; - - taskExecutions: Array; -} - -export namespace TaskExecutionsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface TaskExecutionsPageParams { - pageSize?: number; - - token?: string; -} - -export class TaskExecutionsPage extends AbstractPage implements TaskExecutionsPageResponse { - pagination: TaskExecutionsPageResponse.Pagination; - - taskExecutions: Array; - - constructor( - client: Gitpod, - response: Response, - body: TaskExecutionsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.taskExecutions = body.taskExecutions || []; - } - - getPaginatedItems(): Item[] { - return this.taskExecutions ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface TasksPageResponse { - pagination: TasksPageResponse.Pagination; - - tasks: Array; -} - -export namespace TasksPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface TasksPageParams { - pageSize?: number; - - token?: string; -} - -export class TasksPage extends AbstractPage implements TasksPageResponse { - pagination: TasksPageResponse.Pagination; - - tasks: Array; - - constructor( - client: Gitpod, - response: Response, - body: TasksPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.tasks = body.tasks || []; - } - - getPaginatedItems(): Item[] { - return this.tasks ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - -export interface TokensPageResponse { - pagination: TokensPageResponse.Pagination; - - tokens: Array; -} - -export namespace TokensPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface TokensPageParams { - pageSize?: number; - - token?: string; -} - -export class TokensPage extends AbstractPage implements TokensPageResponse { - pagination: TokensPageResponse.Pagination; - - tokens: Array; - - constructor( - client: Gitpod, - response: Response, - body: TokensPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.pagination = body.pagination || {}; - this.tokens = body.tokens || []; - } - - getPaginatedItems(): Item[] { - return this.tokens ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} +/** @deprecated Import from ./core/pagination instead */ +export * from './core/pagination'; diff --git a/src/resource.ts b/src/resource.ts index ce38897..363e351 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,11 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import type { Gitpod } from './client'; - -export class APIResource { - protected _client: Gitpod; - - constructor(client: Gitpod) { - this._client = client; - } -} +/** @deprecated Import from ./core/resource instead */ +export * from './core/resource'; diff --git a/src/resources/accounts.ts b/src/resources/accounts.ts index 6704ddc..b341c47 100644 --- a/src/resources/accounts.ts +++ b/src/resources/accounts.ts @@ -1,9 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; +import { APIResource } from '../core/resource'; import * as Shared from './shared'; -import { APIPromise } from '../api-promise'; -import { LoginProvidersPage, type LoginProvidersPageParams, PagePromise } from '../pagination'; +import { APIPromise } from '../core/api-promise'; +import { LoginProvidersPage, type LoginProvidersPageParams, PagePromise } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; export class Accounts extends APIResource { diff --git a/src/resources/editors.ts b/src/resources/editors.ts index 11232fc..28832f9 100644 --- a/src/resources/editors.ts +++ b/src/resources/editors.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; -import { APIPromise } from '../api-promise'; -import { EditorsPage, type EditorsPageParams, PagePromise } from '../pagination'; +import { APIResource } from '../core/resource'; +import { APIPromise } from '../core/api-promise'; +import { EditorsPage, type EditorsPageParams, PagePromise } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; export class Editors extends APIResource { diff --git a/src/resources/environments/automations/automations.ts b/src/resources/environments/automations/automations.ts index 9659f33..a369c3c 100644 --- a/src/resources/environments/automations/automations.ts +++ b/src/resources/environments/automations/automations.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as Shared from '../../shared'; import * as ServicesAPI from './services'; import { @@ -40,7 +40,7 @@ import { TaskUpdateResponse, Tasks as TasksAPITasks, } from './tasks/tasks'; -import { APIPromise } from '../../../api-promise'; +import { APIPromise } from '../../../core/api-promise'; import { RequestOptions } from '../../../internal/request-options'; export class Automations extends APIResource { diff --git a/src/resources/environments/automations/services.ts b/src/resources/environments/automations/services.ts index 4089844..6941f18 100644 --- a/src/resources/environments/automations/services.ts +++ b/src/resources/environments/automations/services.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as ServicesAPI from './services'; import * as Shared from '../../shared'; -import { APIPromise } from '../../../api-promise'; -import { PagePromise, ServicesPage, type ServicesPageParams } from '../../../pagination'; +import { APIPromise } from '../../../core/api-promise'; +import { PagePromise, ServicesPage, type ServicesPageParams } from '../../../core/pagination'; import { RequestOptions } from '../../../internal/request-options'; export class Services extends APIResource { diff --git a/src/resources/environments/automations/tasks/executions.ts b/src/resources/environments/automations/tasks/executions.ts index d8bc0cf..47410d8 100644 --- a/src/resources/environments/automations/tasks/executions.ts +++ b/src/resources/environments/automations/tasks/executions.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../../resource'; +import { APIResource } from '../../../../core/resource'; import * as Shared from '../../../shared'; import { TaskExecutionsTaskExecutionsPage } from '../../../shared'; -import { APIPromise } from '../../../../api-promise'; -import { PagePromise, TaskExecutionsPage, type TaskExecutionsPageParams } from '../../../../pagination'; +import { APIPromise } from '../../../../core/api-promise'; +import { PagePromise, TaskExecutionsPage, type TaskExecutionsPageParams } from '../../../../core/pagination'; import { RequestOptions } from '../../../../internal/request-options'; export class Executions extends APIResource { diff --git a/src/resources/environments/automations/tasks/tasks.ts b/src/resources/environments/automations/tasks/tasks.ts index a1e1b97..6a85c1f 100644 --- a/src/resources/environments/automations/tasks/tasks.ts +++ b/src/resources/environments/automations/tasks/tasks.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../../resource'; +import { APIResource } from '../../../../core/resource'; import * as Shared from '../../../shared'; import { TasksTasksPage } from '../../../shared'; import * as ExecutionsAPI from './executions'; @@ -12,8 +12,8 @@ import { ExecutionStopResponse, Executions, } from './executions'; -import { APIPromise } from '../../../../api-promise'; -import { PagePromise, TasksPage, type TasksPageParams } from '../../../../pagination'; +import { APIPromise } from '../../../../core/api-promise'; +import { PagePromise, TasksPage, type TasksPageParams } from '../../../../core/pagination'; import { RequestOptions } from '../../../../internal/request-options'; export class Tasks extends APIResource { diff --git a/src/resources/environments/classes.ts b/src/resources/environments/classes.ts index d1a03ee..709e8bc 100644 --- a/src/resources/environments/classes.ts +++ b/src/resources/environments/classes.ts @@ -1,10 +1,14 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import { EnvironmentClassesEnvironmentClassesPage } from '../shared'; import * as RunnersAPI from '../runners/runners'; -import { EnvironmentClassesPage, type EnvironmentClassesPageParams, PagePromise } from '../../pagination'; +import { + EnvironmentClassesPage, + type EnvironmentClassesPageParams, + PagePromise, +} from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Classes extends APIResource { diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts index ee1390b..2534b7f 100644 --- a/src/resources/environments/environments.ts +++ b/src/resources/environments/environments.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as EnvironmentsAPI from './environments'; import * as Shared from '../shared'; import * as ClassesAPI from './classes'; @@ -14,8 +14,8 @@ import { Automations, AutomationsFile as AutomationsAPIAutomationsFile, } from './automations/automations'; -import { APIPromise } from '../../api-promise'; -import { EnvironmentsPage, type EnvironmentsPageParams, PagePromise } from '../../pagination'; +import { APIPromise } from '../../core/api-promise'; +import { EnvironmentsPage, type EnvironmentsPageParams, PagePromise } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Environments extends APIResource { diff --git a/src/resources/events.ts b/src/resources/events.ts index 927e568..68a011a 100644 --- a/src/resources/events.ts +++ b/src/resources/events.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; +import { APIResource } from '../core/resource'; import * as EventsAPI from './events'; import * as Shared from './shared'; -import { APIPromise } from '../api-promise'; -import { EntriesPage, type EntriesPageParams, PagePromise } from '../pagination'; +import { APIPromise } from '../core/api-promise'; +import { EntriesPage, type EntriesPageParams, PagePromise } from '../core/pagination'; import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; import { JSONLDecoder } from '../internal/decoders/jsonl'; diff --git a/src/resources/groups.ts b/src/resources/groups.ts index b67b15c..56384a4 100644 --- a/src/resources/groups.ts +++ b/src/resources/groups.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; -import { GroupsPage, type GroupsPageParams, PagePromise } from '../pagination'; +import { APIResource } from '../core/resource'; +import { GroupsPage, type GroupsPageParams, PagePromise } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; export class Groups extends APIResource { diff --git a/src/resources/identity.ts b/src/resources/identity.ts index 9bfb3fd..e351965 100644 --- a/src/resources/identity.ts +++ b/src/resources/identity.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; +import { APIResource } from '../core/resource'; import * as Shared from './shared'; -import { APIPromise } from '../api-promise'; +import { APIPromise } from '../core/api-promise'; import { RequestOptions } from '../internal/request-options'; export class Identity extends APIResource { diff --git a/src/resources/organizations/domain-verifications.ts b/src/resources/organizations/domain-verifications.ts index 8fcb6a9..51e3a9e 100644 --- a/src/resources/organizations/domain-verifications.ts +++ b/src/resources/organizations/domain-verifications.ts @@ -1,8 +1,12 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; -import { DomainVerificationsPage, type DomainVerificationsPageParams, PagePromise } from '../../pagination'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { + DomainVerificationsPage, + type DomainVerificationsPageParams, + PagePromise, +} from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class DomainVerifications extends APIResource { diff --git a/src/resources/organizations/invites.ts b/src/resources/organizations/invites.ts index b8f3540..5dded81 100644 --- a/src/resources/organizations/invites.ts +++ b/src/resources/organizations/invites.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; export class Invites extends APIResource { diff --git a/src/resources/organizations/organizations.ts b/src/resources/organizations/organizations.ts index bdba148..b0b452d 100644 --- a/src/resources/organizations/organizations.ts +++ b/src/resources/organizations/organizations.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import * as DomainVerificationsAPI from './domain-verifications'; import { @@ -46,14 +46,14 @@ import { SSOConfigurations, SSOConfigurationsSSOConfigurationsPage, } from './sso-configurations'; -import { APIPromise } from '../../api-promise'; +import { APIPromise } from '../../core/api-promise'; import { MembersPage, type MembersPageParams, OrganizationsPage, type OrganizationsPageParams, PagePromise, -} from '../../pagination'; +} from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Organizations extends APIResource { diff --git a/src/resources/organizations/sso-configurations.ts b/src/resources/organizations/sso-configurations.ts index 83e5205..a447375 100644 --- a/src/resources/organizations/sso-configurations.ts +++ b/src/resources/organizations/sso-configurations.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, SSOConfigurationsPage, type SSOConfigurationsPageParams } from '../../pagination'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { PagePromise, SSOConfigurationsPage, type SSOConfigurationsPageParams } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class SSOConfigurations extends APIResource { diff --git a/src/resources/projects/policies.ts b/src/resources/projects/policies.ts index 07d3d09..ea39ec5 100644 --- a/src/resources/projects/policies.ts +++ b/src/resources/projects/policies.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../pagination'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Policies extends APIResource { diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts index 7ca91c8..3f3967a 100644 --- a/src/resources/projects/projects.ts +++ b/src/resources/projects/projects.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import * as PoliciesAPI from './policies'; import { @@ -16,8 +16,8 @@ import { ProjectPolicy, ProjectRole, } from './policies'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, ProjectsPage, type ProjectsPageParams } from '../../pagination'; +import { APIPromise } from '../../core/api-promise'; +import { PagePromise, ProjectsPage, type ProjectsPageParams } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Projects extends APIResource { diff --git a/src/resources/runners/configurations/configurations.ts b/src/resources/runners/configurations/configurations.ts index 0213678..db30ece 100644 --- a/src/resources/runners/configurations/configurations.ts +++ b/src/resources/runners/configurations/configurations.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as Shared from '../../shared'; import * as EnvironmentClassesAPI from './environment-classes'; import { @@ -47,7 +47,7 @@ import { ScmIntegrations, ScmIntegrationsIntegrationsPage, } from './scm-integrations'; -import { APIPromise } from '../../../api-promise'; +import { APIPromise } from '../../../core/api-promise'; import { RequestOptions } from '../../../internal/request-options'; export class Configurations extends APIResource { diff --git a/src/resources/runners/configurations/environment-classes.ts b/src/resources/runners/configurations/environment-classes.ts index 9e70d73..1db7137 100644 --- a/src/resources/runners/configurations/environment-classes.ts +++ b/src/resources/runners/configurations/environment-classes.ts @@ -1,11 +1,15 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as Shared from '../../shared'; import { EnvironmentClassesEnvironmentClassesPage } from '../../shared'; import * as RunnersAPI from '../runners'; -import { APIPromise } from '../../../api-promise'; -import { EnvironmentClassesPage, type EnvironmentClassesPageParams, PagePromise } from '../../../pagination'; +import { APIPromise } from '../../../core/api-promise'; +import { + EnvironmentClassesPage, + type EnvironmentClassesPageParams, + PagePromise, +} from '../../../core/pagination'; import { RequestOptions } from '../../../internal/request-options'; export class EnvironmentClasses extends APIResource { diff --git a/src/resources/runners/configurations/host-authentication-tokens.ts b/src/resources/runners/configurations/host-authentication-tokens.ts index 0b7240e..8196628 100644 --- a/src/resources/runners/configurations/host-authentication-tokens.ts +++ b/src/resources/runners/configurations/host-authentication-tokens.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; -import { APIPromise } from '../../../api-promise'; -import { PagePromise, TokensPage, type TokensPageParams } from '../../../pagination'; +import { APIResource } from '../../../core/resource'; +import { APIPromise } from '../../../core/api-promise'; +import { PagePromise, TokensPage, type TokensPageParams } from '../../../core/pagination'; import { RequestOptions } from '../../../internal/request-options'; export class HostAuthenticationTokens extends APIResource { diff --git a/src/resources/runners/configurations/schema.ts b/src/resources/runners/configurations/schema.ts index 137908c..a7885dd 100644 --- a/src/resources/runners/configurations/schema.ts +++ b/src/resources/runners/configurations/schema.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; -import { APIPromise } from '../../../api-promise'; +import { APIResource } from '../../../core/resource'; +import { APIPromise } from '../../../core/api-promise'; import { RequestOptions } from '../../../internal/request-options'; export class Schema extends APIResource { diff --git a/src/resources/runners/configurations/scm-integrations.ts b/src/resources/runners/configurations/scm-integrations.ts index d6dcc3f..ebdc52b 100644 --- a/src/resources/runners/configurations/scm-integrations.ts +++ b/src/resources/runners/configurations/scm-integrations.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; -import { APIPromise } from '../../../api-promise'; -import { IntegrationsPage, type IntegrationsPageParams, PagePromise } from '../../../pagination'; +import { APIResource } from '../../../core/resource'; +import { APIPromise } from '../../../core/api-promise'; +import { IntegrationsPage, type IntegrationsPageParams, PagePromise } from '../../../core/pagination'; import { RequestOptions } from '../../../internal/request-options'; export class ScmIntegrations extends APIResource { diff --git a/src/resources/runners/policies.ts b/src/resources/runners/policies.ts index 4b71a77..0cdd4c1 100644 --- a/src/resources/runners/policies.ts +++ b/src/resources/runners/policies.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../pagination'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Policies extends APIResource { diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts index 4efa8a4..0925d50 100644 --- a/src/resources/runners/runners.ts +++ b/src/resources/runners/runners.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as RunnersAPI from './runners'; import * as Shared from '../shared'; import * as PoliciesAPI from './policies'; @@ -26,8 +26,8 @@ import { FieldValidationError, ScmIntegrationValidationResult, } from './configurations/configurations'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, RunnersPage, type RunnersPageParams } from '../../pagination'; +import { APIPromise } from '../../core/api-promise'; +import { PagePromise, RunnersPage, type RunnersPageParams } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Runners extends APIResource { diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts index 845d02e..62ceb78 100644 --- a/src/resources/secrets.ts +++ b/src/resources/secrets.ts @@ -1,9 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; +import { APIResource } from '../core/resource'; import * as Shared from './shared'; -import { APIPromise } from '../api-promise'; -import { PagePromise, SecretsPage, type SecretsPageParams } from '../pagination'; +import { APIPromise } from '../core/api-promise'; +import { PagePromise, SecretsPage, type SecretsPageParams } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; export class Secrets extends APIResource { diff --git a/src/resources/shared.ts b/src/resources/shared.ts index e6c63f1..b771f1d 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Shared from './shared'; -import { EnvironmentClassesPage, TaskExecutionsPage, TasksPage } from '../pagination'; +import { EnvironmentClassesPage, TaskExecutionsPage, TasksPage } from '../core/pagination'; /** * An AutomationTrigger represents a trigger for an automation action. The diff --git a/src/resources/users/pats.ts b/src/resources/users/pats.ts index d8037ac..6827d68 100644 --- a/src/resources/users/pats.ts +++ b/src/resources/users/pats.ts @@ -1,9 +1,13 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; -import { APIPromise } from '../../api-promise'; -import { PagePromise, PersonalAccessTokensPage, type PersonalAccessTokensPageParams } from '../../pagination'; +import { APIPromise } from '../../core/api-promise'; +import { + PagePromise, + PersonalAccessTokensPage, + type PersonalAccessTokensPageParams, +} from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Pats extends APIResource { diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts index 63c3f75..4fb4bad 100644 --- a/src/resources/users/users.ts +++ b/src/resources/users/users.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import * as PatsAPI from './pats'; import { @@ -13,7 +13,7 @@ import { PersonalAccessToken, PersonalAccessTokensPersonalAccessTokensPage, } from './pats'; -import { APIPromise } from '../../api-promise'; +import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; export class Users extends APIResource { diff --git a/src/uploads.ts b/src/uploads.ts index 79d3073..b2ef647 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1,2 +1,2 @@ -export { type Uploadable } from './internal/uploads'; -export { toFile, type ToFileInput } from './internal/to-file'; +/** @deprecated Import from ./core/uploads instead */ +export * from './core/uploads'; diff --git a/tests/form.test.ts b/tests/form.test.ts index 1dd9656..cb575ba 100644 --- a/tests/form.test.ts +++ b/tests/form.test.ts @@ -1,5 +1,5 @@ import { multipartFormRequestOptions, createForm } from '@gitpod/sdk/internal/uploads'; -import { toFile } from '@gitpod/sdk/uploads'; +import { toFile } from '@gitpod/sdk/core/uploads'; describe('form data validation', () => { test('valid values do not error', async () => { diff --git a/tests/index.test.ts b/tests/index.test.ts index 24fd099..afe3fed 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIPromise } from '@gitpod/sdk/api-promise'; +import { APIPromise } from '@gitpod/sdk/core/api-promise'; import util from 'node:util'; import Gitpod from '@gitpod/sdk'; diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 7b28bb5..d18eb6c 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import type { ResponseLike } from '@gitpod/sdk/internal/to-file'; -import { toFile } from '@gitpod/sdk/uploads'; +import { toFile } from '@gitpod/sdk/core/uploads'; import { File } from 'node:buffer'; class MyClass { @@ -97,7 +97,7 @@ describe('missing File error message', () => { }); test('is thrown', async () => { - const uploads = await import('@gitpod/sdk/uploads'); + const uploads = await import('@gitpod/sdk/core/uploads'); await expect( uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), ).rejects.toMatchInlineSnapshot( From dab243394f6b0f60cedc65f3eabcf1bfe64ed640 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 06:54:56 +0000 Subject: [PATCH 21/46] fix(client): send `X-Stainless-Timeout` in seconds (#63) --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index ef0b007..8f973c0 100644 --- a/src/client.ts +++ b/src/client.ts @@ -835,7 +835,7 @@ export class Gitpod { Accept: 'application/json', 'User-Agent': this.getUserAgent(), 'X-Stainless-Retry-Count': String(retryCount), - ...(options.timeout ? { 'X-Stainless-Timeout': String(options.timeout) } : {}), + ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}), ...getPlatformHeaders(), }, this.authHeaders(options), From 38e00c9995d8528c361bf709d3951a0f00238ada Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 07:20:40 +0000 Subject: [PATCH 22/46] chore(internal): add aliases for Record and Array (#64) --- src/internal/builtin-types.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/internal/builtin-types.ts b/src/internal/builtin-types.ts index b2e598a..c23d3bd 100644 --- a/src/internal/builtin-types.ts +++ b/src/internal/builtin-types.ts @@ -39,9 +39,23 @@ type _HeadersInit = RequestInit['headers']; */ type _BodyInit = RequestInit['body']; +/** + * An alias to the builtin `Array` type so we can + * easily alias it in import statements if there are name clashes. + */ +type _Array = Array; + +/** + * An alias to the builtin `Record` type so we can + * easily alias it in import statements if there are name clashes. + */ +type _Record = Record; + export type { + _Array as Array, _BodyInit as BodyInit, _HeadersInit as HeadersInit, + _Record as Record, _RequestInfo as RequestInfo, _RequestInit as RequestInit, _Response as Response, From 62c4790ed0515d7644fca6075b5d9304bd4b1642 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 08:18:11 +0000 Subject: [PATCH 23/46] chore(client): make jsonl methods consistent with other streaming methods (#65) --- api.md | 2 +- src/resources/events.ts | 5 +- tests/internal/decoders/line.test.ts | 128 +++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 tests/internal/decoders/line.test.ts diff --git a/api.md b/api.md index 8e80f38..4a2d257 100644 --- a/api.md +++ b/api.md @@ -174,7 +174,7 @@ Types: Methods: - client.events.list({ ...params }) -> EventListResponsesEntriesPage -- client.events.watch({ ...params }) -> JSONLDecoder<EventWatchResponse> +- client.events.watch({ ...params }) -> EventWatchResponse # Groups diff --git a/src/resources/events.ts b/src/resources/events.ts index 68a011a..bc5d412 100644 --- a/src/resources/events.ts +++ b/src/resources/events.ts @@ -79,9 +79,12 @@ export class Events extends APIResource { { 'Content-Type': 'application/jsonl', Accept: 'application/jsonl' }, options?.headers, ]), + stream: true, __binaryResponse: true, }) - ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); + ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)) as APIPromise< + JSONLDecoder + >; } } diff --git a/tests/internal/decoders/line.test.ts b/tests/internal/decoders/line.test.ts new file mode 100644 index 0000000..9f45693 --- /dev/null +++ b/tests/internal/decoders/line.test.ts @@ -0,0 +1,128 @@ +import { findDoubleNewlineIndex, LineDecoder } from '@gitpod/sdk/internal/decoders/line'; + +function decodeChunks(chunks: string[], { flush }: { flush: boolean } = { flush: false }): string[] { + const decoder = new LineDecoder(); + const lines: string[] = []; + for (const chunk of chunks) { + lines.push(...decoder.decode(chunk)); + } + + if (flush) { + lines.push(...decoder.flush()); + } + + return lines; +} + +describe('line decoder', () => { + test('basic', () => { + // baz is not included because the line hasn't ended yet + expect(decodeChunks(['foo', ' bar\nbaz'])).toEqual(['foo bar']); + }); + + test('basic with \\r', () => { + expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']); + expect(decodeChunks(['foo', ' bar\r\nbaz'], { flush: true })).toEqual(['foo bar', 'baz']); + }); + + test('trailing new lines', () => { + expect(decodeChunks(['foo', ' bar', 'baz\n', 'thing\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('trailing new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar', 'baz\r\n', 'thing\r\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('escaped new lines', () => { + expect(decodeChunks(['foo', ' bar\\nbaz\n'])).toEqual(['foo bar\\nbaz']); + }); + + test('escaped new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']); + }); + + test('\\r & \\n split across multiple chunks', () => { + expect(decodeChunks(['foo\r', '\n', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('single \\r', () => { + expect(decodeChunks(['foo\r', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('double \\r', () => { + expect(decodeChunks(['foo\r', 'bar\r'], { flush: true })).toEqual(['foo', 'bar']); + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + // implementation detail that we don't yield the single \r line until a new \r or \n is encountered + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: false })).toEqual(['foo']); + }); + + test('double \\r then \\r\\n', () => { + expect(decodeChunks(['foo\r', '\r', '\r', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + }); + + test('double newline', () => { + expect(decodeChunks(['foo\n\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('multi-byte characters across chunks', () => { + const decoder = new LineDecoder(); + + // bytes taken from the string 'известни' and arbitrarily split + // so that some multi-byte characters span multiple chunks + expect(decoder.decode(new Uint8Array([0xd0]))).toHaveLength(0); + expect(decoder.decode(new Uint8Array([0xb8, 0xd0, 0xb7, 0xd0]))).toHaveLength(0); + expect( + decoder.decode(new Uint8Array([0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb8])), + ).toHaveLength(0); + + const decoded = decoder.decode(new Uint8Array([0xa])); + expect(decoded).toEqual(['известни']); + }); + + test('flushing trailing newlines', () => { + expect(decodeChunks(['foo\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('flushing empty buffer', () => { + expect(decodeChunks([], { flush: true })).toEqual([]); + }); +}); + +describe('findDoubleNewlineIndex', () => { + test('finds \\n\\n', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\nbar'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\nbar'))).toBe(2); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\n'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\n'))).toBe(2); + }); + + test('finds \\r\\r', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\rbar'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\rbar'))).toBe(2); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\r'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\r'))).toBe(2); + }); + + test('finds \\r\\n\\r\\n', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\nbar'))).toBe(7); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\nbar'))).toBe(4); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\n'))).toBe(7); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\n'))).toBe(4); + }); + + test('returns -1 when no double newline found', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\nbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\rbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\nbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode(''))).toBe(-1); + }); + + test('handles incomplete patterns', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n'))).toBe(-1); + }); +}); From 8aa007bc39d87e8b96861748a23d4faa5d084c8a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 08:28:47 +0000 Subject: [PATCH 24/46] fix(api): improve type resolution when importing as a package (#66) --- packages/mcp-server/src/tools.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/mcp-server/src/tools.ts diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts new file mode 100644 index 0000000..7e516de --- /dev/null +++ b/packages/mcp-server/src/tools.ts @@ -0,0 +1 @@ +export * from './tools/index'; From 65686bf96f2a2147c620810605bc66876ec0c13e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 02:20:11 +0000 Subject: [PATCH 25/46] fix(mcp): remove unused tools.ts (#67) --- packages/mcp-server/src/tools.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/mcp-server/src/tools.ts diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts deleted file mode 100644 index 7e516de..0000000 --- a/packages/mcp-server/src/tools.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './tools/index'; From 3ced7939c98da7bc8c42a457da3aee4510a778a7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 02:49:49 +0000 Subject: [PATCH 26/46] fix(client): send all configured auth headers (#68) --- src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 8f973c0..08e24e7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -385,8 +385,8 @@ export class Gitpod { return; } - protected authHeaders(opts: FinalRequestOptions): Headers | undefined { - return new Headers({ Authorization: `Bearer ${this.bearerToken}` }); + protected authHeaders(opts: FinalRequestOptions): NullableHeaders | undefined { + return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]); } /** From af4a60aa5f1bc957cdb96b0996f4ee02c0d7d469 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 02:30:31 +0000 Subject: [PATCH 27/46] chore(tests): improve enum examples (#69) --- tests/api-resources/organizations/organizations.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api-resources/organizations/organizations.test.ts b/tests/api-resources/organizations/organizations.test.ts index f88e6bd..16be6a5 100644 --- a/tests/api-resources/organizations/organizations.test.ts +++ b/tests/api-resources/organizations/organizations.test.ts @@ -179,7 +179,7 @@ describe('resource organizations', () => { const response = await client.organizations.setRole({ organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', - role: 'ORGANIZATION_ROLE_UNSPECIFIED', + role: 'ORGANIZATION_ROLE_MEMBER', }); }); }); From dbd4446148041e01ec058c0a19568a17ad7384f7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 02:36:11 +0000 Subject: [PATCH 28/46] chore(internal): upload builds and expand CI branch coverage --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++---------- scripts/utils/upload-artifact.sh | 25 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) create mode 100755 scripts/utils/upload-artifact.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0312165..5e6495e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,19 +1,18 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'preview-head/**' + - 'preview-base/**' + - 'preview/**' jobs: lint: name: lint runs-on: ubuntu-latest - - steps: - uses: actions/checkout@v4 @@ -31,8 +30,9 @@ jobs: build: name: build runs-on: ubuntu-latest - - + permissions: + contents: read + id-token: write steps: - uses: actions/checkout@v4 @@ -46,10 +46,24 @@ jobs: - name: Check build run: ./scripts/build + + - name: Get GitHub OIDC Token + if: github.repository == 'stainless-sdks/gitpod-typescript' + id: github-oidc + uses: actions/github-script@v6 + with: + script: core.setOutput('github_token', await core.getIDToken()); + + - name: Upload tarball + if: github.repository == 'stainless-sdks/gitpod-typescript' + env: + URL: https://pkg.stainless.com/s + AUTH: ${{ steps.github-oidc.outputs.github_token }} + SHA: ${{ github.sha }} + run: ./scripts/utils/upload-artifact.sh test: name: test runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh new file mode 100755 index 0000000..864a4c8 --- /dev/null +++ b/scripts/utils/upload-artifact.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -exuo pipefail + +RESPONSE=$(curl -X POST "$URL" \ + -H "Authorization: Bearer $AUTH" \ + -H "Content-Type: application/json") + +SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url') + +if [[ "$SIGNED_URL" == "null" ]]; then + echo -e "\033[31mFailed to get signed URL.\033[0m" + exit 1 +fi + +UPLOAD_RESPONSE=$(tar -cz dist | curl -v -X PUT \ + -H "Content-Type: application/gzip" \ + --data-binary @- "$SIGNED_URL" 2>&1) + +if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then + echo -e "\033[32mUploaded build to Stainless storage.\033[0m" + echo -e "\033[32mInstallation: npm install 'https://pkg.stainless.com/s/gitpod-typescript/$SHA'\033[0m" +else + echo -e "\033[31mFailed to upload artifact.\033[0m" + exit 1 +fi From 726127ae7ad639fc5587724e20559893ea3c67eb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 02:38:28 +0000 Subject: [PATCH 29/46] chore(internal): improve node 18 shims --- package.json | 4 ++ scripts/build | 2 - src/internal/shims/crypto.node.d.mts | 1 - src/internal/shims/crypto.node.d.ts | 10 ---- src/internal/shims/crypto.node.js | 11 ---- src/internal/shims/crypto.node.mjs | 2 - src/internal/shims/crypto.ts | 18 ++++++ src/internal/shims/file.node.d.mts | 1 - src/internal/shims/file.node.d.ts | 20 ------- src/internal/shims/file.node.js | 11 ---- src/internal/shims/file.node.mjs | 2 - src/internal/shims/file.ts | 32 +++++++++++ src/internal/shims/getBuiltinModule.ts | 64 ++++++++++++++++++++++ src/internal/shims/nullGetBuiltinModule.ts | 1 + src/internal/to-file.ts | 4 +- src/internal/uploads.ts | 9 +-- src/internal/utils/uuid.ts | 16 ++++-- tests/uploads.test.ts | 2 +- 18 files changed, 136 insertions(+), 74 deletions(-) delete mode 100644 src/internal/shims/crypto.node.d.mts delete mode 100644 src/internal/shims/crypto.node.d.ts delete mode 100644 src/internal/shims/crypto.node.js delete mode 100644 src/internal/shims/crypto.node.mjs create mode 100644 src/internal/shims/crypto.ts delete mode 100644 src/internal/shims/file.node.d.mts delete mode 100644 src/internal/shims/file.node.d.ts delete mode 100644 src/internal/shims/file.node.js delete mode 100644 src/internal/shims/file.node.mjs create mode 100644 src/internal/shims/file.ts create mode 100644 src/internal/shims/getBuiltinModule.ts create mode 100644 src/internal/shims/nullGetBuiltinModule.ts diff --git a/package.json b/package.json index dae603a..e99d450 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,10 @@ "resolutions": { "synckit": "0.8.8" }, + "browser": { + "./internal/shims/getBuiltinModule.mjs": "./internal/shims/nullGetBuiltinModule.mjs", + "./internal/shims/getBuiltinModule.js": "./internal/shims/nullGetBuiltinModule.js" + }, "imports": { "@gitpod/sdk": ".", "@gitpod/sdk/*": "./src/*" diff --git a/scripts/build b/scripts/build index 047fe3d..afc1898 100755 --- a/scripts/build +++ b/scripts/build @@ -35,8 +35,6 @@ node scripts/utils/fix-index-exports.cjs cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts -mkdir -p dist/internal/shims -cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts deleted file mode 100644 index 5cc1963..0000000 --- a/src/internal/shims/crypto.node.d.mts +++ /dev/null @@ -1 +0,0 @@ -export { crypto } from './crypto.node.js'; diff --git a/src/internal/shims/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts deleted file mode 100644 index dc7caac..0000000 --- a/src/internal/shims/crypto.node.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export declare const crypto: { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ - getRandomValues(array: T): T; - /** - * Available only in secure contexts. - * - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) - */ - randomUUID?: () => string; -}; diff --git a/src/internal/shims/crypto.node.js b/src/internal/shims/crypto.node.js deleted file mode 100644 index 83062a3..0000000 --- a/src/internal/shims/crypto.node.js +++ /dev/null @@ -1,11 +0,0 @@ -if (typeof require !== 'undefined') { - if (globalThis.crypto) { - exports.crypto = globalThis.crypto; - } else { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // crypto module. - exports.crypto = [require][0]('node:crypto').webcrypto; - } catch (e) {} - } -} diff --git a/src/internal/shims/crypto.node.mjs b/src/internal/shims/crypto.node.mjs deleted file mode 100644 index 24c6f3b..0000000 --- a/src/internal/shims/crypto.node.mjs +++ /dev/null @@ -1,2 +0,0 @@ -import * as mod from './crypto.node.js'; -export const crypto = globalThis.crypto || mod.crypto; diff --git a/src/internal/shims/crypto.ts b/src/internal/shims/crypto.ts new file mode 100644 index 0000000..905f81c --- /dev/null +++ b/src/internal/shims/crypto.ts @@ -0,0 +1,18 @@ +import { getBuiltinModule } from './getBuiltinModule'; + +type Crypto = { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ + getRandomValues(array: T): T; + /** + * Available only in secure contexts. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) + */ + randomUUID?: () => string; +}; +export let getCrypto: () => Crypto | undefined = function lazyGetCrypto() { + if (getCrypto !== lazyGetCrypto) return getCrypto(); + const crypto: Crypto = (globalThis as any).crypto || (getBuiltinModule?.('node:crypto') as any)?.webcrypto; + getCrypto = () => crypto; + return crypto; +}; diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts deleted file mode 100644 index 38cc9ff..0000000 --- a/src/internal/shims/file.node.d.mts +++ /dev/null @@ -1 +0,0 @@ -export { File } from './file.node.js'; diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts deleted file mode 100644 index 9dc6b2f..0000000 --- a/src/internal/shims/file.node.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -// The infer is to make TS show it as a nice union type, -// instead of literally `ConstructorParameters[0]` -type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; -/** - * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. - */ -declare class FallbackFile extends Blob { - constructor(sources: FallbackBlobSource, fileName: string, options?: any); - /** - * The name of the `File`. - */ - readonly name: string; - /** - * The last modified date of the `File`. - */ - readonly lastModified: number; -} -export type File = InstanceType; -export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor -: typeof FallbackFile; diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js deleted file mode 100644 index 3f8c2ed..0000000 --- a/src/internal/shims/file.node.js +++ /dev/null @@ -1,11 +0,0 @@ -if (typeof require !== 'undefined') { - if (globalThis.File) { - exports.File = globalThis.File; - } else { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // buffer module. - exports.File = [require][0]('node:buffer').File; - } catch (e) {} - } -} diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs deleted file mode 100644 index 1f103f5..0000000 --- a/src/internal/shims/file.node.mjs +++ /dev/null @@ -1,2 +0,0 @@ -import * as mod from './file.node.js'; -export const File = globalThis.File || mod.File; diff --git a/src/internal/shims/file.ts b/src/internal/shims/file.ts new file mode 100644 index 0000000..d5dc820 --- /dev/null +++ b/src/internal/shims/file.ts @@ -0,0 +1,32 @@ +import { getBuiltinModule } from './getBuiltinModule'; + +export let getFile = function lazyGetFile(): FileConstructor { + if (getFile !== lazyGetFile) return getFile(); + // We can drop getBuiltinModule once we no longer support Node < 20.0.0 + const File = (globalThis as any).File ?? (getBuiltinModule?.('node:buffer') as any)?.File; + if (!File) throw new Error('`File` is not defined as a global, which is required for file uploads.'); + getFile = () => File; + return File; +}; + +type FileConstructor = + typeof globalThis extends { File: infer fileConstructor } ? fileConstructor : typeof FallbackFile; +export type File = InstanceType; + +// The infer is to make TS show it as a nice union type, +// instead of literally `ConstructorParameters[0]` +type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; +/** + * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. + */ +declare class FallbackFile extends Blob { + constructor(sources: FallbackBlobSource, fileName: string, options?: any); + /** + * The name of the `File`. + */ + readonly name: string; + /** + * The last modified date of the `File`. + */ + readonly lastModified: number; +} diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts new file mode 100644 index 0000000..a202f20 --- /dev/null +++ b/src/internal/shims/getBuiltinModule.ts @@ -0,0 +1,64 @@ +/** + * Load a Node built-in module. ID may or may not be prefixed by `node:` and + * will be normalized. If we used static imports then our bundle size would be bloated by + * injected polyfills, and if we used dynamic require then in addition to bundlers logging warnings, + * our code would not work when bundled to ESM and run in Node 18. + * @param {string} id ID of the built-in to be loaded. + * @returns {object|undefined} exports of the built-in. Undefined if the built-in + * does not exist. + */ +export let getBuiltinModule: null | ((id: string) => object | undefined) = function getBuiltinModuleLazy( + id: string, +): object | undefined { + try { + if (getBuiltinModule !== getBuiltinModuleLazy) return getBuiltinModule!(id); + if ((process as any).getBuiltinModule) { + getBuiltinModule = (process as any).getBuiltinModule; + } else { + /* Fallback implementation for Node 18 */ + function createFallbackGetBuiltinModule(BuiltinModule: any) { + return function getBuiltinModule(id: string): object | undefined { + id = BuiltinModule.normalizeRequirableId(String(id)); + if (!BuiltinModule.canBeRequiredByUsers(id)) { + return; + } + const mod = BuiltinModule.map.get(id); + mod.compileForPublicLoader(); + return mod.exports; + }; + } + const magicKey = Math.random() + ''; + let module: { BuiltinModule: any } | undefined; + try { + const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( + (e) => e.description?.includes('clone'), + )!; + Object.defineProperty(Object.prototype, magicKey, { + get() { + module = this; + throw null; + }, + configurable: true, + }); + structuredClone( + new (class extends Blob { + [kClone]() { + return { + deserializeInfo: 'internal/bootstrap/realm:' + magicKey, + }; + } + })([]), + ); + } catch {} + delete (Object.prototype as any)[magicKey]; + if (module) { + getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); + } else { + getBuiltinModule = () => undefined; + } + } + return getBuiltinModule!(id); + } catch { + return undefined; + } +}; diff --git a/src/internal/shims/nullGetBuiltinModule.ts b/src/internal/shims/nullGetBuiltinModule.ts new file mode 100644 index 0000000..8bd2280 --- /dev/null +++ b/src/internal/shims/nullGetBuiltinModule.ts @@ -0,0 +1 @@ +export const getBuiltinModule = null; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index 69b76d3..e92ac69 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -1,4 +1,4 @@ -import { File } from './shims/file.node.js'; +import { type File, getFile } from './shims/file'; import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; import type { FilePropertyBag } from './builtin-types'; @@ -90,7 +90,7 @@ export async function toFile( // If we've been given a `File` we don't need to do anything if (isFileLike(value)) { - if (File && value instanceof File) { + if (value instanceof getFile()) { return value; } return makeFile([await value.arrayBuffer()], value.name); diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index e09bcbb..fa0627a 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,7 +1,7 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; import type { Gitpod } from '../client'; -import { File } from './shims/file.node.js'; +import { type File, getFile } from './shims/file'; import { ReadableStreamFrom } from './shims'; export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; @@ -32,10 +32,7 @@ export function makeFile( fileName: string | undefined, options?: FilePropertyBag, ): File { - if (typeof File === 'undefined') { - throw new Error('`File` is not defined as a global which is required for file uploads'); - } - + const File = getFile(); return new File(fileBits as any, fileName ?? 'unknown_file', options); } @@ -129,7 +126,7 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. const isNamedBlob = (value: object) => - (File && value instanceof File) || (value instanceof Blob && 'name' in value); + value instanceof getFile() || (value instanceof Blob && 'name' in value); const isUploadable = (value: unknown) => typeof value === 'object' && diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 1349c42..5a262c6 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,13 +1,19 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { crypto } from '../shims/crypto.node.js'; +import { getCrypto } from '../shims/crypto'; /** * https://stackoverflow.com/a/2117523 */ -export function uuid4() { - if (crypto.randomUUID) return crypto.randomUUID(); +export let uuid4 = function () { + const crypto = getCrypto(); + if (crypto?.randomUUID) { + uuid4 = crypto.randomUUID.bind(crypto); + return crypto.randomUUID(); + } + const u8 = new Uint8Array(1); + const randomByte = crypto ? () => crypto.getRandomValues(u8)[0]! : () => (Math.random() * 0xff) & 0xff; return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => - (+c ^ (crypto.getRandomValues(new Uint8Array(1))[0]! & (15 >> (+c / 4)))).toString(16), + (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16), ); -} +}; diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index d18eb6c..27bf8b3 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -101,7 +101,7 @@ describe('missing File error message', () => { await expect( uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), ).rejects.toMatchInlineSnapshot( - `[Error: \`File\` is not defined as a global which is required for file uploads]`, + `[Error: \`File\` is not defined as a global, which is required for file uploads.]`, ); }); }); From e8cd029655896872fa1ccd8b71807f8c0ac565c9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 02:40:38 +0000 Subject: [PATCH 30/46] chore(internal): reduce CI branch coverage --- .github/workflows/ci.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e6495e..4864646 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,12 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'preview-head/**' - - 'preview-base/**' - - 'preview/**' + branches: + - main + pull_request: + branches: + - main + - next jobs: lint: From 702757cc250c54fa31731233f3b88841b42baa32 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 02:18:00 +0000 Subject: [PATCH 31/46] fix(internal): fix file uploads in node 18 jest --- src/internal/shims/getBuiltinModule.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts index a202f20..64daa2c 100644 --- a/src/internal/shims/getBuiltinModule.ts +++ b/src/internal/shims/getBuiltinModule.ts @@ -29,11 +29,13 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct } const magicKey = Math.random() + ''; let module: { BuiltinModule: any } | undefined; + let ObjectPrototype: {} = Blob; + for (let next; (next = Reflect.getPrototypeOf(ObjectPrototype)); ObjectPrototype = next); try { const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( (e) => e.description?.includes('clone'), )!; - Object.defineProperty(Object.prototype, magicKey, { + Object.defineProperty(ObjectPrototype, magicKey, { get() { module = this; throw null; @@ -50,7 +52,7 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct })([]), ); } catch {} - delete (Object.prototype as any)[magicKey]; + delete (ObjectPrototype as any)[magicKey]; if (module) { getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); } else { From e3c6fb879bc94b55e66f65a5238102ba390387a8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 02:50:59 +0000 Subject: [PATCH 32/46] chore(client): minor internal fixes --- src/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.ts b/src/client.ts index 08e24e7..8db32fe 100644 --- a/src/client.ts +++ b/src/client.ts @@ -786,17 +786,17 @@ export class Gitpod { } buildRequest( - options: FinalRequestOptions, + inputOptions: FinalRequestOptions, { retryCount = 0 }: { retryCount?: number } = {}, ): { req: FinalizedRequestInit; url: string; timeout: number } { - options = { ...options }; + const options = { ...inputOptions }; const { method, path, query } = options; const url = this.buildURL(path!, query as Record); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); options.timeout = options.timeout ?? this.timeout; const { bodyHeaders, body } = this.buildBody({ options }); - const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount }); + const reqHeaders = this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount }); const req: FinalizedRequestInit = { method, From b3a1e96efe94fd726a49c050eb1a6e0069171983 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 03:13:35 +0000 Subject: [PATCH 33/46] chore(perf): faster base64 decoding --- src/internal/utils/base64.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts index 50d616c..725fbda 100644 --- a/src/internal/utils/base64.ts +++ b/src/internal/utils/base64.ts @@ -22,15 +22,17 @@ export const toBase64 = (data: string | Uint8Array | null | undefined): string = export const fromBase64 = (str: string): Uint8Array => { if (typeof (globalThis as any).Buffer !== 'undefined') { - return new Uint8Array((globalThis as any).Buffer.from(str, 'base64')); + const buf = (globalThis as any).Buffer.from(str, 'base64'); + return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength); } if (typeof atob !== 'undefined') { - return new Uint8Array( - atob(str) - .split('') - .map((c) => c.charCodeAt(0)), - ); + const bstr = atob(str); + const buf = new Uint8Array(bstr.length); + for (let i = 0; i < bstr.length; i++) { + buf[i] = bstr.charCodeAt(i); + } + return buf; } throw new GitpodError('Cannot decode base64 string; Expected `Buffer` or `atob` to be defined'); From d78258ce7b00f01f7714c59bda0d12d3f70b7ec3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 03:18:10 +0000 Subject: [PATCH 34/46] chore(ci): add timeout thresholds for CI jobs --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4864646..43d363e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: jobs: lint: + timeout-minutes: 10 name: lint runs-on: ubuntu-latest steps: @@ -27,6 +28,7 @@ jobs: run: ./scripts/lint build: + timeout-minutes: 5 name: build runs-on: ubuntu-latest permissions: @@ -61,6 +63,7 @@ jobs: SHA: ${{ github.sha }} run: ./scripts/utils/upload-artifact.sh test: + timeout-minutes: 10 name: test runs-on: ubuntu-latest steps: From c60c38f7f805d86e56d6a2f96c742b1549d62e5c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 02:31:00 +0000 Subject: [PATCH 35/46] chore(internal): codegen related update --- .github/workflows/ci.yml | 18 +++++++++--------- .github/workflows/publish-npm.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43d363e..221b21a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,18 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -30,7 +30,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 permissions: contents: read id-token: write @@ -65,7 +65,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index d11b246..224f0d7 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: publish - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 742b303..07e7079 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -8,7 +8,7 @@ on: jobs: release_doctor: name: release doctor - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 if: github.repository == 'gitpod-io/gitpod-sdk-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: From 678516c59e2a0a39caa817aa847f9a3f197172b7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 02:31:37 +0000 Subject: [PATCH 36/46] chore(ci): only use depot for staging repos --- .github/workflows/ci.yml | 6 +++--- .github/workflows/publish-npm.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 221b21a..8c21a27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 @@ -30,7 +30,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} permissions: contents: read id-token: write @@ -65,7 +65,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 224f0d7..d11b246 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: publish - runs-on: depot-ubuntu-24.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 07e7079..742b303 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -8,7 +8,7 @@ on: jobs: release_doctor: name: release doctor - runs-on: depot-ubuntu-24.04 + runs-on: ubuntu-latest if: github.repository == 'gitpod-io/gitpod-sdk-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: From eafa310bb3964addb8bbbf8c8811564f6985068e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:56:55 +0000 Subject: [PATCH 37/46] chore(internal): refactor utils --- src/client.ts | 10 +++--- src/internal/decoders/line.ts | 67 ++++++----------------------------- src/internal/headers.ts | 5 +-- src/internal/utils/base64.ts | 9 ++--- src/internal/utils/bytes.ts | 32 +++++++++++++++++ 5 files changed, 56 insertions(+), 67 deletions(-) create mode 100644 src/internal/utils/bytes.ts diff --git a/src/client.ts b/src/client.ts index 8db32fe..3aadcfe 100644 --- a/src/client.ts +++ b/src/client.ts @@ -700,12 +700,12 @@ export class Gitpod { fetchOptions.method = method.toUpperCase(); } - return ( + try { // use undefined this binding; fetch errors if bound to something else in browser/cloudflare - this.fetch.call(undefined, url, fetchOptions).finally(() => { - clearTimeout(timeout); - }) - ); + return await this.fetch.call(undefined, url, fetchOptions); + } finally { + clearTimeout(timeout); + } } private shouldRetry(response: Response): boolean { diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index a4c237f..b3bfa97 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -1,4 +1,4 @@ -import { GitpodError } from '../../core/error'; +import { concatBytes, decodeUTF8, encodeUTF8 } from '../utils/bytes'; export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; @@ -13,16 +13,11 @@ export class LineDecoder { static NEWLINE_CHARS = new Set(['\n', '\r']); static NEWLINE_REGEXP = /\r\n|[\n\r]/g; - buffer: Uint8Array; + #buffer: Uint8Array; #carriageReturnIndex: number | null; - textDecoder: - | undefined - | { - decode(buffer: Uint8Array | ArrayBuffer): string; - }; constructor() { - this.buffer = new Uint8Array(); + this.#buffer = new Uint8Array(); this.#carriageReturnIndex = null; } @@ -33,17 +28,14 @@ export class LineDecoder { const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? new TextEncoder().encode(chunk) + : typeof chunk === 'string' ? encodeUTF8(chunk) : chunk; - let newData = new Uint8Array(this.buffer.length + binaryChunk.length); - newData.set(this.buffer); - newData.set(binaryChunk, this.buffer.length); - this.buffer = newData; + this.#buffer = concatBytes([this.#buffer, binaryChunk]); const lines: string[] = []; let patternIndex; - while ((patternIndex = findNewlineIndex(this.buffer, this.#carriageReturnIndex)) != null) { + while ((patternIndex = findNewlineIndex(this.#buffer, this.#carriageReturnIndex)) != null) { if (patternIndex.carriage && this.#carriageReturnIndex == null) { // skip until we either get a corresponding `\n`, a new `\r` or nothing this.#carriageReturnIndex = patternIndex.index; @@ -55,8 +47,8 @@ export class LineDecoder { this.#carriageReturnIndex != null && (patternIndex.index !== this.#carriageReturnIndex + 1 || patternIndex.carriage) ) { - lines.push(this.decodeText(this.buffer.slice(0, this.#carriageReturnIndex - 1))); - this.buffer = this.buffer.slice(this.#carriageReturnIndex); + lines.push(decodeUTF8(this.#buffer.subarray(0, this.#carriageReturnIndex - 1))); + this.#buffer = this.#buffer.subarray(this.#carriageReturnIndex); this.#carriageReturnIndex = null; continue; } @@ -64,55 +56,18 @@ export class LineDecoder { const endIndex = this.#carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding; - const line = this.decodeText(this.buffer.slice(0, endIndex)); + const line = decodeUTF8(this.#buffer.subarray(0, endIndex)); lines.push(line); - this.buffer = this.buffer.slice(patternIndex.index); + this.#buffer = this.#buffer.subarray(patternIndex.index); this.#carriageReturnIndex = null; } return lines; } - decodeText(bytes: Bytes): string { - if (bytes == null) return ''; - if (typeof bytes === 'string') return bytes; - - // Node: - if (typeof (globalThis as any).Buffer !== 'undefined') { - if (bytes instanceof (globalThis as any).Buffer) { - return bytes.toString(); - } - if (bytes instanceof Uint8Array) { - return (globalThis as any).Buffer.from(bytes).toString(); - } - - throw new GitpodError( - `Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`, - ); - } - - // Browser - if (typeof (globalThis as any).TextDecoder !== 'undefined') { - if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { - this.textDecoder ??= new (globalThis as any).TextDecoder('utf8'); - return this.textDecoder!.decode(bytes); - } - - throw new GitpodError( - `Unexpected: received non-Uint8Array/ArrayBuffer (${ - (bytes as any).constructor.name - }) in a web platform. Please report this error.`, - ); - } - - throw new GitpodError( - `Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`, - ); - } - flush(): string[] { - if (!this.buffer.length) { + if (!this.#buffer.length) { return []; } return this.decode('\n'); diff --git a/src/internal/headers.ts b/src/internal/headers.ts index a110a12..8659dde 100644 --- a/src/internal/headers.ts +++ b/src/internal/headers.ts @@ -3,7 +3,7 @@ type HeaderValue = string | undefined | null; export type HeadersLike = | Headers - | readonly [string, HeaderValue][] + | readonly HeaderValue[][] | Record | undefined | null @@ -40,7 +40,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator; + let iter: Iterable; if (headers instanceof Headers) { iter = headers.entries(); } else if (isArray(headers)) { @@ -51,6 +51,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator { if (!data) return ''; - if (typeof data === 'string') { - data = new (globalThis as any).TextEncoder().encode(data); - } - if (typeof (globalThis as any).Buffer !== 'undefined') { return (globalThis as any).Buffer.from(data).toString('base64'); } + if (typeof data === 'string') { + data = encodeUTF8(data); + } + if (typeof btoa !== 'undefined') { return btoa(String.fromCharCode.apply(null, data as any)); } diff --git a/src/internal/utils/bytes.ts b/src/internal/utils/bytes.ts new file mode 100644 index 0000000..8da627a --- /dev/null +++ b/src/internal/utils/bytes.ts @@ -0,0 +1,32 @@ +export function concatBytes(buffers: Uint8Array[]): Uint8Array { + let length = 0; + for (const buffer of buffers) { + length += buffer.length; + } + const output = new Uint8Array(length); + let index = 0; + for (const buffer of buffers) { + output.set(buffer, index); + index += buffer.length; + } + + return output; +} + +let encodeUTF8_: (str: string) => Uint8Array; +export function encodeUTF8(str: string) { + let encoder; + return ( + encodeUTF8_ ?? + ((encoder = new (globalThis as any).TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))) + )(str); +} + +let decodeUTF8_: (bytes: Uint8Array) => string; +export function decodeUTF8(bytes: Uint8Array) { + let decoder; + return ( + decodeUTF8_ ?? + ((decoder = new (globalThis as any).TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))) + )(bytes); +} From fea4ecb31efa7b73aec94c3aed1f574b80611110 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 03:36:12 +0000 Subject: [PATCH 38/46] docs(readme): fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cbfd5f..a2f50c6 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ async function main() { main(); ``` -Error codes are as followed: +Error codes are as follows: | Status Code | Error Type | | ----------- | -------------------------- | From e94c55895af8caf60720420c33c1e22c6e2d5bd4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 3 May 2025 02:38:17 +0000 Subject: [PATCH 39/46] chore(internal): codegen related update --- .devcontainer/devcontainer.json | 4 +--- .github/workflows/release-doctor.yml | 1 - package.json | 2 +- release-please-config.json | 5 +---- scripts/build | 6 +++++- scripts/format | 4 ++++ tsconfig.build.json | 2 +- tsconfig.json | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 763462f..43fd5a7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -9,9 +9,7 @@ "postCreateCommand": "yarn install", "customizations": { "vscode": { - "extensions": [ - "esbenp.prettier-vscode" - ] + "extensions": ["esbenp.prettier-vscode"] } } } diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 742b303..f875bac 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.GITPOD_NPM_TOKEN || secrets.NPM_TOKEN }} - diff --git a/package.json b/package.json index e99d450..46025d4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "test": "./scripts/test", "build": "./scripts/build", "prepublishOnly": "echo 'to publish, run yarn build && (cd dist; yarn publish)' && exit 1", - "format": "prettier --write --cache --cache-strategy metadata . !dist", + "format": "./scripts/format", "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build && ./scripts/utils/git-swap.sh; fi", "tsn": "ts-node -r tsconfig-paths/register", "lint": "./scripts/lint", diff --git a/release-please-config.json b/release-please-config.json index 624ed99..1ebd0bd 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -60,8 +60,5 @@ } ], "release-type": "node", - "extra-files": [ - "src/version.ts", - "README.md" - ] + "extra-files": ["src/version.ts", "README.md"] } diff --git a/scripts/build b/scripts/build index afc1898..3323742 100755 --- a/scripts/build +++ b/scripts/build @@ -19,9 +19,13 @@ for file in LICENSE CHANGELOG.md; do if [ -e "${file}" ]; then cp "${file}" dist; fi done if [ -e "bin/cli" ]; then - mkdir dist/bin + mkdir -p dist/bin cp -p "bin/cli" dist/bin/; fi +if [ -e "bin/migration-config.json" ]; then + mkdir -p dist/bin + cp -p "bin/migration-config.json" dist/bin/; +fi # this converts the export map paths for the dist directory # and does a few other minor things node scripts/utils/make-dist-package-json.cjs > dist/package.json diff --git a/scripts/format b/scripts/format index 903b1ef..7a75640 100755 --- a/scripts/format +++ b/scripts/format @@ -6,3 +6,7 @@ cd "$(dirname "$0")/.." 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' diff --git a/tsconfig.build.json b/tsconfig.build.json index 269698c..0460cd2 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -6,7 +6,7 @@ "rootDir": "./dist/src", "paths": { "@gitpod/sdk/*": ["dist/src/*"], - "@gitpod/sdk": ["dist/src/index.ts"], + "@gitpod/sdk": ["dist/src/index.ts"] }, "noEmit": false, "declaration": true, diff --git a/tsconfig.json b/tsconfig.json index 4ae7ffe..db8ba0b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,7 +31,7 @@ "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, - "isolatedModules": false, + "isolatedModules": false, "skipLibCheck": true } From b52aa0747ab51dbdf0eeb63e3fce2c255f47a06c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 3 May 2025 02:39:00 +0000 Subject: [PATCH 40/46] chore(internal): share typescript helpers --- package.json | 10 ++-- tsc-multi.json | 4 +- yarn.lock | 128 ++++++++++++++++++++++++------------------------- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 46025d4..615f6e6 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "@types/node": "^20.17.6", "@types/ssh2": "^1.15.4", "@types/sshpk": "^1.17.4", - "@typescript-eslint/eslint-plugin": "^8.24.0", - "@typescript-eslint/parser": "^8.24.0", + "@typescript-eslint/eslint-plugin": "8.31.1", + "@typescript-eslint/parser": "8.31.1", "eslint": "^9.20.1", "eslint-plugin-prettier": "^5.2.3", "eslint-plugin-unused-imports": "^4.1.4", @@ -45,10 +45,10 @@ "sshpk": "^1.18.0", "ts-jest": "^29.1.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz", "tsconfig-paths": "^4.0.0", - "typescript": "^4.8.2", - "typescript-eslint": "^8.24.0" + "typescript": "5.8.3", + "typescript-eslint": "8.31.1" }, "resolutions": { "synckit": "0.8.8" diff --git a/tsc-multi.json b/tsc-multi.json index 4facad5..170bac7 100644 --- a/tsc-multi.json +++ b/tsc-multi.json @@ -1,7 +1,7 @@ { "targets": [ - { "extname": ".js", "module": "commonjs" }, - { "extname": ".mjs", "module": "esnext" } + { "extname": ".js", "module": "commonjs", "shareHelpers": "internal/tslib.js" }, + { "extname": ".mjs", "module": "esnext", "shareHelpers": "internal/tslib.mjs" } ], "projects": ["tsconfig.build.json"] } diff --git a/yarn.lock b/yarn.lock index 6c01b49..414e05d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -990,62 +990,62 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@8.24.0", "@typescript-eslint/eslint-plugin@^8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz#574a95d67660a1e4544ae131d672867a5b40abb3" - integrity sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ== +"@typescript-eslint/eslint-plugin@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz#62f1befe59647524994e89de4516d8dcba7a850a" + integrity sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/type-utils" "8.24.0" - "@typescript-eslint/utils" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/type-utils" "8.31.1" + "@typescript-eslint/utils" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^2.0.1" -"@typescript-eslint/parser@8.24.0", "@typescript-eslint/parser@^8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.24.0.tgz#bba837f9ee125b78f459ad947ff9b61be8139085" - integrity sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA== +"@typescript-eslint/parser@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.31.1.tgz#e9b0ccf30d37dde724ee4d15f4dbc195995cce1b" + integrity sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q== dependencies: - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/typescript-estree" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz#2e34b3eb2ce768f2ffb109474174ced5417002b1" - integrity sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw== +"@typescript-eslint/scope-manager@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz#1eb52e76878f545e4add142e0d8e3e97e7aa443b" + integrity sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw== dependencies: - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" -"@typescript-eslint/type-utils@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz#6ee3ec4db06f9e5e7b01ca6c2b5dd5843a9fd1e8" - integrity sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA== +"@typescript-eslint/type-utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz#be0f438fb24b03568e282a0aed85f776409f970c" + integrity sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA== dependencies: - "@typescript-eslint/typescript-estree" "8.24.0" - "@typescript-eslint/utils" "8.24.0" + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/utils" "8.31.1" debug "^4.3.4" ts-api-utils "^2.0.1" -"@typescript-eslint/types@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.24.0.tgz#694e7fb18d70506c317b816de9521300b0f72c8e" - integrity sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw== +"@typescript-eslint/types@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.31.1.tgz#478ed6f7e8aee1be7b63a60212b6bffe1423b5d4" + integrity sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ== -"@typescript-eslint/typescript-estree@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz#0487349be174097bb329a58273100a9629e03c6c" - integrity sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ== +"@typescript-eslint/typescript-estree@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz#37792fe7ef4d3021c7580067c8f1ae66daabacdf" + integrity sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag== dependencies: - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -1053,22 +1053,22 @@ semver "^7.6.0" ts-api-utils "^2.0.1" -"@typescript-eslint/utils@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.24.0.tgz#21cb1195ae79230af825bfeed59574f5cb70a749" - integrity sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ== +"@typescript-eslint/utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.31.1.tgz#5628ea0393598a0b2f143d0fc6d019f0dee9dd14" + integrity sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/typescript-estree" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" -"@typescript-eslint/visitor-keys@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz#36ecf0b9b1d819ad88a3bd4157ab7d594cb797c9" - integrity sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg== +"@typescript-eslint/visitor-keys@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz#6742b0e3ba1e0c1e35bdaf78c03e759eb8dd8e75" + integrity sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw== dependencies: - "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/types" "8.31.1" eslint-visitor-keys "^4.2.0" acorn-jsx@^5.3.2: @@ -3403,9 +3403,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.3/tsc-multi.tgz": - version "1.1.3" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz#8fc21fc95b247b86721b95fabfb10c6a436134c3" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz": + version "1.1.4" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz#cbed459a9e902f5295ec3daaf1c7aa3b10427e55" dependencies: debug "^4.3.7" fast-glob "^3.3.2" @@ -3459,24 +3459,24 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript-eslint@^8.24.0: - version "8.24.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.0.tgz#cc655e71885ecb8280342b422ad839a2e2e46a96" - integrity sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ== +typescript-eslint@8.31.1: + version "8.31.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.31.1.tgz#b77ab1e48ced2daab9225ff94bab54391a4af69b" + integrity sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA== dependencies: - "@typescript-eslint/eslint-plugin" "8.24.0" - "@typescript-eslint/parser" "8.24.0" - "@typescript-eslint/utils" "8.24.0" + "@typescript-eslint/eslint-plugin" "8.31.1" + "@typescript-eslint/parser" "8.31.1" + "@typescript-eslint/utils" "8.31.1" typescript@5.6.1-rc: version "5.6.1-rc" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.1-rc.tgz#d5e4d7d8170174fed607b74cc32aba3d77018e02" integrity sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ== -typescript@^4.8.2: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== undici-types@~5.26.4: version "5.26.5" From f50f5adf1ea13bb39845ff8644e2f670bc01856d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 09:04:45 +0000 Subject: [PATCH 41/46] feat(api): manual updates --- .stats.yml | 8 +- api.md | 35 ++- src/client.ts | 28 +-- src/core/pagination.ts | 55 ----- src/resources/editors.ts | 31 ++- .../environments/automations/services.ts | 11 + src/resources/environments/environments.ts | 65 ++++++ src/resources/environments/index.ts | 2 + src/resources/events.ts | 8 +- src/resources/identity.ts | 8 + src/resources/index.ts | 10 +- src/resources/organizations/index.ts | 12 +- src/resources/organizations/organizations.ts | 118 +++------- src/resources/organizations/policies.ts | 217 ++++++++++++++++++ src/resources/projects/projects.ts | 30 +++ .../runners/configurations/schema.ts | 56 +++++ src/resources/runners/index.ts | 2 + src/resources/runners/runners.ts | 88 ++++++- src/resources/secrets.ts | 62 ++--- src/resources/shared.ts | 6 + src/resources/users/dotfiles.ts | 89 +++++++ src/resources/users/index.ts | 8 + src/resources/users/users.ts | 20 ++ .../environments/environments.test.ts | 21 ++ .../organizations/organizations.test.ts | 12 - .../organizations/policies.test.ts | 61 +++++ tests/api-resources/projects/projects.test.ts | 1 + tests/api-resources/users/dotfiles.test.ts | 34 +++ 28 files changed, 887 insertions(+), 211 deletions(-) create mode 100644 src/resources/organizations/policies.ts create mode 100644 src/resources/users/dotfiles.ts create mode 100644 tests/api-resources/organizations/policies.test.ts create mode 100644 tests/api-resources/users/dotfiles.test.ts diff --git a/.stats.yml b/.stats.yml index e8f1d28..ef4c630 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 111 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3655d5ad0ac3e228c1519af70dbf3d0bfa3c47a2d06d4cac92a650da051b49a6.yml -openapi_spec_hash: 5dbb5577e6a7cae7db615b1b06c9d23e -config_hash: 719ad411c0ec7402a7a4c1f95515280c +configured_endpoints: 115 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml +openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d +config_hash: 981e43e8b1e3ddabd435d350aeeed417 diff --git a/api.md b/api.md index 4a2d257..82689ae 100644 --- a/api.md +++ b/api.md @@ -68,6 +68,7 @@ Types: - EnvironmentRetrieveResponse - EnvironmentUpdateResponse - EnvironmentDeleteResponse +- EnvironmentCreateEnvironmentTokenResponse - EnvironmentCreateFromProjectResponse - EnvironmentCreateLogsTokenResponse - EnvironmentMarkActiveResponse @@ -81,6 +82,7 @@ Methods: - client.environments.update({ ...params }) -> unknown - client.environments.list({ ...params }) -> EnvironmentsEnvironmentsPage - client.environments.delete({ ...params }) -> unknown +- client.environments.createEnvironmentToken({ ...params }) -> EnvironmentCreateEnvironmentTokenResponse - client.environments.createFromProject({ ...params }) -> EnvironmentCreateFromProjectResponse - client.environments.createLogsToken({ ...params }) -> EnvironmentCreateLogsTokenResponse - client.environments.markActive({ ...params }) -> unknown @@ -190,6 +192,7 @@ Methods: Types: +- IDTokenVersion - IdentityExchangeTokenResponse - IdentityGetAuthenticatedIdentityResponse - IdentityGetIDTokenResponse @@ -207,7 +210,7 @@ Types: - InviteDomains - Organization - OrganizationMember -- Scope +- OrganizationTier - OrganizationCreateResponse - OrganizationRetrieveResponse - OrganizationUpdateResponse @@ -221,7 +224,6 @@ Methods: - client.organizations.create({ ...params }) -> OrganizationCreateResponse - client.organizations.retrieve({ ...params }) -> OrganizationRetrieveResponse - client.organizations.update({ ...params }) -> OrganizationUpdateResponse -- client.organizations.list({ ...params }) -> OrganizationsOrganizationsPage - client.organizations.delete({ ...params }) -> unknown - client.organizations.join({ ...params }) -> OrganizationJoinResponse - client.organizations.leave({ ...params }) -> unknown @@ -262,6 +264,19 @@ Methods: - client.organizations.invites.retrieve({ ...params }) -> InviteRetrieveResponse - client.organizations.invites.getSummary({ ...params }) -> InviteGetSummaryResponse +## Policies + +Types: + +- OrganizationPolicies +- PolicyRetrieveResponse +- PolicyUpdateResponse + +Methods: + +- client.organizations.policies.retrieve({ ...params }) -> PolicyRetrieveResponse +- client.organizations.policies.update({ ...params }) -> unknown + ## SSOConfigurations Types: @@ -326,6 +341,8 @@ Methods: Types: +- LogLevel +- MetricsConfiguration - Runner - RunnerCapability - RunnerConfiguration @@ -453,6 +470,7 @@ Methods: Types: - Secret +- SecretScope - SecretCreateResponse - SecretDeleteResponse - SecretGetValueResponse @@ -479,6 +497,19 @@ Methods: - client.users.getAuthenticatedUser({ ...params }) -> UserGetAuthenticatedUserResponse - client.users.setSuspended({ ...params }) -> unknown +## Dotfiles + +Types: + +- DotfilesConfiguration +- DotfileGetResponse +- DotfileSetResponse + +Methods: + +- client.users.dotfiles.get({ ...params }) -> DotfileGetResponse +- client.users.dotfiles.set({ ...params }) -> unknown + ## Pats Types: diff --git a/src/client.ts b/src/client.ts index 3aadcfe..e9880cc 100644 --- a/src/client.ts +++ b/src/client.ts @@ -35,8 +35,6 @@ import { LoginProvidersPageResponse, type MembersPageParams, MembersPageResponse, - type OrganizationsPageParams, - OrganizationsPageResponse, type PersonalAccessTokensPageParams, PersonalAccessTokensPageResponse, type PoliciesPageParams, @@ -101,6 +99,7 @@ import { } from './resources/events'; import { Group, GroupListParams, Groups, GroupsGroupsPage } from './resources/groups'; import { + IDTokenVersion, Identity, IdentityExchangeTokenParams, IdentityExchangeTokenResponse, @@ -118,6 +117,7 @@ import { SecretGetValueParams, SecretGetValueResponse, SecretListParams, + SecretScope, SecretUpdateValueParams, SecretUpdateValueResponse, Secrets, @@ -130,6 +130,8 @@ import { AdmissionLevel, Environment, EnvironmentActivitySignal, + EnvironmentCreateEnvironmentTokenParams, + EnvironmentCreateEnvironmentTokenResponse, EnvironmentCreateFromProjectParams, EnvironmentCreateFromProjectResponse, EnvironmentCreateLogsTokenParams, @@ -168,18 +170,16 @@ import { OrganizationLeaveParams, OrganizationLeaveResponse, OrganizationListMembersParams, - OrganizationListParams, OrganizationMember, OrganizationMembersMembersPage, OrganizationRetrieveParams, OrganizationRetrieveResponse, OrganizationSetRoleParams, OrganizationSetRoleResponse, + OrganizationTier, OrganizationUpdateParams, OrganizationUpdateResponse, Organizations, - OrganizationsOrganizationsPage, - Scope, } from './resources/organizations/organizations'; import { EnvironmentInitializer, @@ -201,6 +201,8 @@ import { ProjectsProjectsPage, } from './resources/projects/projects'; import { + LogLevel, + MetricsConfiguration, Runner, RunnerCapability, RunnerCheckAuthenticationForHostParams, @@ -973,12 +975,6 @@ export declare namespace Gitpod { export import MembersPage = Pagination.MembersPage; export { type MembersPageParams as MembersPageParams, type MembersPageResponse as MembersPageResponse }; - export import OrganizationsPage = Pagination.OrganizationsPage; - export { - type OrganizationsPageParams as OrganizationsPageParams, - type OrganizationsPageResponse as OrganizationsPageResponse, - }; - export import PersonalAccessTokensPage = Pagination.PersonalAccessTokensPage; export { type PersonalAccessTokensPageParams as PersonalAccessTokensPageParams, @@ -1058,6 +1054,7 @@ export declare namespace Gitpod { type EnvironmentRetrieveResponse as EnvironmentRetrieveResponse, type EnvironmentUpdateResponse as EnvironmentUpdateResponse, type EnvironmentDeleteResponse as EnvironmentDeleteResponse, + type EnvironmentCreateEnvironmentTokenResponse as EnvironmentCreateEnvironmentTokenResponse, type EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse, type EnvironmentCreateLogsTokenResponse as EnvironmentCreateLogsTokenResponse, type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse, @@ -1069,6 +1066,7 @@ export declare namespace Gitpod { type EnvironmentUpdateParams as EnvironmentUpdateParams, type EnvironmentListParams as EnvironmentListParams, type EnvironmentDeleteParams as EnvironmentDeleteParams, + type EnvironmentCreateEnvironmentTokenParams as EnvironmentCreateEnvironmentTokenParams, type EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams, type EnvironmentCreateLogsTokenParams as EnvironmentCreateLogsTokenParams, type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams, @@ -1096,6 +1094,7 @@ export declare namespace Gitpod { export { Identity as Identity, + type IDTokenVersion as IDTokenVersion, type IdentityExchangeTokenResponse as IdentityExchangeTokenResponse, type IdentityGetAuthenticatedIdentityResponse as IdentityGetAuthenticatedIdentityResponse, type IdentityGetIDTokenResponse as IdentityGetIDTokenResponse, @@ -1109,7 +1108,7 @@ export declare namespace Gitpod { type InviteDomains as InviteDomains, type Organization as Organization, type OrganizationMember as OrganizationMember, - type Scope as Scope, + type OrganizationTier as OrganizationTier, type OrganizationCreateResponse as OrganizationCreateResponse, type OrganizationRetrieveResponse as OrganizationRetrieveResponse, type OrganizationUpdateResponse as OrganizationUpdateResponse, @@ -1117,12 +1116,10 @@ export declare namespace Gitpod { type OrganizationJoinResponse as OrganizationJoinResponse, type OrganizationLeaveResponse as OrganizationLeaveResponse, type OrganizationSetRoleResponse as OrganizationSetRoleResponse, - type OrganizationsOrganizationsPage as OrganizationsOrganizationsPage, type OrganizationMembersMembersPage as OrganizationMembersMembersPage, type OrganizationCreateParams as OrganizationCreateParams, type OrganizationRetrieveParams as OrganizationRetrieveParams, type OrganizationUpdateParams as OrganizationUpdateParams, - type OrganizationListParams as OrganizationListParams, type OrganizationDeleteParams as OrganizationDeleteParams, type OrganizationJoinParams as OrganizationJoinParams, type OrganizationLeaveParams as OrganizationLeaveParams, @@ -1152,6 +1149,8 @@ export declare namespace Gitpod { export { Runners as Runners, + type LogLevel as LogLevel, + type MetricsConfiguration as MetricsConfiguration, type Runner as Runner, type RunnerCapability as RunnerCapability, type RunnerConfiguration as RunnerConfiguration, @@ -1182,6 +1181,7 @@ export declare namespace Gitpod { export { Secrets as Secrets, type Secret as Secret, + type SecretScope as SecretScope, type SecretCreateResponse as SecretCreateResponse, type SecretDeleteResponse as SecretDeleteResponse, type SecretGetValueResponse as SecretGetValueResponse, diff --git a/src/core/pagination.ts b/src/core/pagination.ts index 5ae7b97..250b4fc 100644 --- a/src/core/pagination.ts +++ b/src/core/pagination.ts @@ -608,61 +608,6 @@ export class MembersPage extends AbstractPage implements MembersPage } } -export interface OrganizationsPageResponse { - organizations: Array; - - pagination: OrganizationsPageResponse.Pagination; -} - -export namespace OrganizationsPageResponse { - export interface Pagination { - nextToken?: string; - } -} - -export interface OrganizationsPageParams { - pageSize?: number; - - token?: string; -} - -export class OrganizationsPage extends AbstractPage implements OrganizationsPageResponse { - organizations: Array; - - pagination: OrganizationsPageResponse.Pagination; - - constructor( - client: Gitpod, - response: Response, - body: OrganizationsPageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.organizations = body.organizations || []; - this.pagination = body.pagination || {}; - } - - getPaginatedItems(): Item[] { - return this.organizations ?? []; - } - - nextPageRequestOptions(): PageRequestOptions | null { - const cursor = this.pagination?.nextToken; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - token: cursor, - }, - }; - } -} - export interface PersonalAccessTokensPageResponse { pagination: PersonalAccessTokensPageResponse.Pagination; diff --git a/src/resources/editors.ts b/src/resources/editors.ts index 28832f9..84853ac 100644 --- a/src/resources/editors.ts +++ b/src/resources/editors.ts @@ -29,7 +29,8 @@ export class Editors extends APIResource { } /** - * Lists all available code editors. + * Lists all available code editors, optionally filtered to those allowed in an + * organization. * * Use this method to: * @@ -48,6 +49,18 @@ export class Editors extends APIResource { * pagination: * pageSize: 20 * ``` + * + * - List editors available to the organization: + * + * Shows all available editors that are allowed by the policies enforced in the + * organization with pagination. + * + * ```yaml + * pagination: + * pageSize: 20 + * filter: + * allowedByPolicy: true + * ``` */ list(params: EditorListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -126,6 +139,11 @@ export interface EditorRetrieveParams { } export interface EditorListParams extends EditorsPageParams { + /** + * Body param: filter contains the filter options for listing editors + */ + filter?: EditorListParams.Filter; + /** * Body param: pagination contains the pagination options for listing environments */ @@ -133,6 +151,17 @@ export interface EditorListParams extends EditorsPageParams { } export namespace EditorListParams { + /** + * filter contains the filter options for listing editors + */ + export interface Filter { + /** + * allowed_by_policy filters the response to only editors that are allowed by the + * policies enforced in the organization + */ + allowedByPolicy?: boolean; + } + /** * pagination contains the pagination options for listing environments */ diff --git a/src/resources/environments/automations/services.ts b/src/resources/environments/automations/services.ts index 6941f18..efd2c80 100644 --- a/src/resources/environments/automations/services.ts +++ b/src/resources/environments/automations/services.ts @@ -393,6 +393,12 @@ export interface ServiceStatus { */ logUrl?: string; + /** + * output contains the output of the service. setting an output field to empty + * string will unset it. + */ + output?: Record; + /** * phase is the current phase of the service. */ @@ -507,6 +513,11 @@ export namespace ServiceUpdateParams { logUrl?: string | null; + /** + * setting an output field to empty string will unset it. + */ + output?: Record; + phase?: ServicesAPI.ServicePhase | null; session?: string | null; diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts index 2534b7f..695ee9e 100644 --- a/src/resources/environments/environments.ts +++ b/src/resources/environments/environments.ts @@ -255,6 +255,32 @@ export class Environments extends APIResource { return this._client.post('/gitpod.v1.EnvironmentService/DeleteEnvironment', { body, ...options }); } + /** + * Creates an access token for the environment. + * + * Generated tokens are valid for one hour and provide environment-specific access + * permissions. The token is scoped to a specific environment. + * + * ### Examples + * + * - Generate environment token: + * + * Creates a temporary access token for accessing an environment. + * + * ```yaml + * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" + * ``` + */ + createEnvironmentToken( + body: EnvironmentCreateEnvironmentTokenParams, + options?: RequestOptions, + ): APIPromise { + return this._client.post('/gitpod.v1.EnvironmentService/CreateEnvironmentAccessToken', { + body, + ...options, + }); + } + /** * Creates an environment from an existing project configuration and starts it. * @@ -618,6 +644,12 @@ export namespace EnvironmentSpec { * devcontainer is the devcontainer spec of the environment */ export interface Devcontainer { + /** + * default_devcontainer_image is the default image that is used to start the + * devcontainer if no devcontainer config file is found + */ + defaultDevcontainerImage?: string; + /** * devcontainer_file_path is the path to the devcontainer file relative to the repo * root path must not be absolute (start with a /): @@ -678,6 +710,11 @@ export namespace EnvironmentSpec { } export interface Secret { + /** + * id is the unique identifier of the secret. + */ + id?: string; + /** * container_registry_basic_auth_host is the hostname of the container registry * that supports basic auth @@ -862,6 +899,12 @@ export namespace EnvironmentStatus { * environment. */ session?: string; + + /** + * warning_message contains warnings, e.g. when no triggers are defined in the + * automations file. + */ + warningMessage?: string; } /** @@ -1162,6 +1205,11 @@ export namespace EnvironmentStatus { } export interface Secret { + /** + * id is the unique identifier of the secret. + */ + id?: string; + /** * failure_message contains the reason the secret failed to be materialize. */ @@ -1226,6 +1274,13 @@ export type EnvironmentUpdateResponse = unknown; export type EnvironmentDeleteResponse = unknown; +export interface EnvironmentCreateEnvironmentTokenResponse { + /** + * access_token is the token that can be used for environment authentication + */ + accessToken: string; +} + export interface EnvironmentCreateFromProjectResponse { /** * +resource get environment @@ -1482,6 +1537,14 @@ export interface EnvironmentDeleteParams { force?: boolean; } +export interface EnvironmentCreateEnvironmentTokenParams { + /** + * environment_id specifies the environment for which the access token should be + * created. + */ + environmentId: string; +} + export interface EnvironmentCreateFromProjectParams { projectId?: string; @@ -1547,6 +1610,7 @@ export declare namespace Environments { type EnvironmentRetrieveResponse as EnvironmentRetrieveResponse, type EnvironmentUpdateResponse as EnvironmentUpdateResponse, type EnvironmentDeleteResponse as EnvironmentDeleteResponse, + type EnvironmentCreateEnvironmentTokenResponse as EnvironmentCreateEnvironmentTokenResponse, type EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse, type EnvironmentCreateLogsTokenResponse as EnvironmentCreateLogsTokenResponse, type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse, @@ -1558,6 +1622,7 @@ export declare namespace Environments { type EnvironmentUpdateParams as EnvironmentUpdateParams, type EnvironmentListParams as EnvironmentListParams, type EnvironmentDeleteParams as EnvironmentDeleteParams, + type EnvironmentCreateEnvironmentTokenParams as EnvironmentCreateEnvironmentTokenParams, type EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams, type EnvironmentCreateLogsTokenParams as EnvironmentCreateLogsTokenParams, type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams, diff --git a/src/resources/environments/index.ts b/src/resources/environments/index.ts index f72333e..4378540 100644 --- a/src/resources/environments/index.ts +++ b/src/resources/environments/index.ts @@ -20,6 +20,7 @@ export { type EnvironmentRetrieveResponse, type EnvironmentUpdateResponse, type EnvironmentDeleteResponse, + type EnvironmentCreateEnvironmentTokenResponse, type EnvironmentCreateFromProjectResponse, type EnvironmentCreateLogsTokenResponse, type EnvironmentMarkActiveResponse, @@ -30,6 +31,7 @@ export { type EnvironmentUpdateParams, type EnvironmentListParams, type EnvironmentDeleteParams, + type EnvironmentCreateEnvironmentTokenParams, type EnvironmentCreateFromProjectParams, type EnvironmentCreateLogsTokenParams, type EnvironmentMarkActiveParams, diff --git a/src/resources/events.ts b/src/resources/events.ts index bc5d412..109d1aa 100644 --- a/src/resources/events.ts +++ b/src/resources/events.ts @@ -116,7 +116,13 @@ export type ResourceType = | 'RESOURCE_TYPE_SERVICE_ACCOUNT' | 'RESOURCE_TYPE_SECRET' | 'RESOURCE_TYPE_SSO_CONFIG' - | 'RESOURCE_TYPE_DOMAIN_VERIFICATION'; + | 'RESOURCE_TYPE_DOMAIN_VERIFICATION' + | 'RESOURCE_TYPE_AGENT_EXECUTION' + | 'RESOURCE_TYPE_RUNNER_LLM_INTEGRATION' + | 'RESOURCE_TYPE_AGENT' + | 'RESOURCE_TYPE_ENVIRONMENT_SESSION' + | 'RESOURCE_TYPE_USER_SECRET' + | 'RESOURCE_TYPE_ORGANIZATION_POLICY'; export interface EventListResponse { id?: string; diff --git a/src/resources/identity.ts b/src/resources/identity.ts index e351965..d1fa01f 100644 --- a/src/resources/identity.ts +++ b/src/resources/identity.ts @@ -97,6 +97,8 @@ export class Identity extends APIResource { } } +export type IDTokenVersion = 'ID_TOKEN_VERSION_UNSPECIFIED' | 'ID_TOKEN_VERSION_V1' | 'ID_TOKEN_VERSION_V2'; + export interface IdentityExchangeTokenResponse { /** * access_token is the new access token @@ -130,10 +132,16 @@ export interface IdentityGetAuthenticatedIdentityParams { export interface IdentityGetIDTokenParams { audience?: Array; + + /** + * version is the version of the ID token. + */ + version?: IDTokenVersion; } export declare namespace Identity { export { + type IDTokenVersion as IDTokenVersion, type IdentityExchangeTokenResponse as IdentityExchangeTokenResponse, type IdentityGetAuthenticatedIdentityResponse as IdentityGetAuthenticatedIdentityResponse, type IdentityGetIDTokenResponse as IdentityGetIDTokenResponse, diff --git a/src/resources/index.ts b/src/resources/index.ts index 5a58cc0..be1edca 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -39,6 +39,7 @@ export { type EnvironmentRetrieveResponse, type EnvironmentUpdateResponse, type EnvironmentDeleteResponse, + type EnvironmentCreateEnvironmentTokenResponse, type EnvironmentCreateFromProjectResponse, type EnvironmentCreateLogsTokenResponse, type EnvironmentMarkActiveResponse, @@ -49,6 +50,7 @@ export { type EnvironmentUpdateParams, type EnvironmentListParams, type EnvironmentDeleteParams, + type EnvironmentCreateEnvironmentTokenParams, type EnvironmentCreateFromProjectParams, type EnvironmentCreateLogsTokenParams, type EnvironmentMarkActiveParams, @@ -69,6 +71,7 @@ export { export { Groups, type Group, type GroupListParams, type GroupsGroupsPage } from './groups'; export { Identity, + type IDTokenVersion, type IdentityExchangeTokenResponse, type IdentityGetAuthenticatedIdentityResponse, type IdentityGetIDTokenResponse, @@ -81,7 +84,7 @@ export { type InviteDomains, type Organization, type OrganizationMember, - type Scope, + type OrganizationTier, type OrganizationCreateResponse, type OrganizationRetrieveResponse, type OrganizationUpdateResponse, @@ -92,13 +95,11 @@ export { type OrganizationCreateParams, type OrganizationRetrieveParams, type OrganizationUpdateParams, - type OrganizationListParams, type OrganizationDeleteParams, type OrganizationJoinParams, type OrganizationLeaveParams, type OrganizationListMembersParams, type OrganizationSetRoleParams, - type OrganizationsOrganizationsPage, type OrganizationMembersMembersPage, } from './organizations/organizations'; export { @@ -122,6 +123,8 @@ export { } from './projects/projects'; export { Runners, + type LogLevel, + type MetricsConfiguration, type Runner, type RunnerCapability, type RunnerConfiguration, @@ -151,6 +154,7 @@ export { export { Secrets, type Secret, + type SecretScope, type SecretCreateResponse, type SecretDeleteResponse, type SecretGetValueResponse, diff --git a/src/resources/organizations/index.ts b/src/resources/organizations/index.ts index f9b1e8f..a023d54 100644 --- a/src/resources/organizations/index.ts +++ b/src/resources/organizations/index.ts @@ -30,7 +30,7 @@ export { type InviteDomains, type Organization, type OrganizationMember, - type Scope, + type OrganizationTier, type OrganizationCreateResponse, type OrganizationRetrieveResponse, type OrganizationUpdateResponse, @@ -41,15 +41,21 @@ export { type OrganizationCreateParams, type OrganizationRetrieveParams, type OrganizationUpdateParams, - type OrganizationListParams, type OrganizationDeleteParams, type OrganizationJoinParams, type OrganizationLeaveParams, type OrganizationListMembersParams, type OrganizationSetRoleParams, - type OrganizationsOrganizationsPage, type OrganizationMembersMembersPage, } from './organizations'; +export { + Policies, + type OrganizationPolicies, + type PolicyRetrieveResponse, + type PolicyUpdateResponse, + type PolicyRetrieveParams, + type PolicyUpdateParams, +} from './policies'; export { SSOConfigurations, type ProviderType, diff --git a/src/resources/organizations/organizations.ts b/src/resources/organizations/organizations.ts index b0b452d..2393f17 100644 --- a/src/resources/organizations/organizations.ts +++ b/src/resources/organizations/organizations.ts @@ -29,6 +29,15 @@ import { Invites, OrganizationInvite, } from './invites'; +import * as PoliciesAPI from './policies'; +import { + OrganizationPolicies, + Policies, + PolicyRetrieveParams, + PolicyRetrieveResponse, + PolicyUpdateParams, + PolicyUpdateResponse, +} from './policies'; import * as SSOConfigurationsAPI from './sso-configurations'; import { ProviderType, @@ -47,19 +56,14 @@ import { SSOConfigurationsSSOConfigurationsPage, } from './sso-configurations'; import { APIPromise } from '../../core/api-promise'; -import { - MembersPage, - type MembersPageParams, - OrganizationsPage, - type OrganizationsPageParams, - PagePromise, -} from '../../core/pagination'; +import { MembersPage, type MembersPageParams, PagePromise } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Organizations extends APIResource { domainVerifications: DomainVerificationsAPI.DomainVerifications = new DomainVerificationsAPI.DomainVerifications(this._client); invites: InvitesAPI.Invites = new InvitesAPI.Invites(this._client); + policies: PoliciesAPI.Policies = new PoliciesAPI.Policies(this._client); ssoConfigurations: SSOConfigurationsAPI.SSOConfigurations = new SSOConfigurationsAPI.SSOConfigurations( this._client, ); @@ -165,49 +169,6 @@ export class Organizations extends APIResource { return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganization', { body, ...options }); } - /** - * Lists all organizations the caller has access to with optional filtering. - * - * Use this method to: - * - * - View organizations you're a member of - * - Browse all available organizations - * - Paginate through organization results - * - * ### Examples - * - * - List member organizations: - * - * Shows organizations where the caller is a member. - * - * ```yaml - * pagination: - * pageSize: 20 - * scope: SCOPE_MEMBER - * ``` - * - * - List all organizations: - * - * Shows all organizations visible to the caller. - * - * ```yaml - * pagination: - * pageSize: 50 - * scope: SCOPE_ALL - * ``` - */ - list( - params: OrganizationListParams, - options?: RequestOptions, - ): PagePromise { - const { token, pageSize, ...body } = params; - return this._client.getAPIList( - '/gitpod.v1.OrganizationService/ListOrganizations', - OrganizationsPage, - { query: { token, pageSize }, body, method: 'post', ...options }, - ); - } - /** * Permanently deletes an organization. * @@ -370,8 +331,6 @@ export class Organizations extends APIResource { } } -export type OrganizationsOrganizationsPage = OrganizationsPage; - export type OrganizationMembersMembersPage = MembersPage; export interface InviteDomains { @@ -478,6 +437,11 @@ export interface Organization { name: string; + /** + * The tier of the organization - free or enterprise + */ + tier: OrganizationTier; + /** * A Timestamp represents a point in time independent of any time zone or local * calendar, encoded as a count of seconds and fractions of seconds at nanosecond @@ -684,7 +648,10 @@ export interface OrganizationMember { avatarUrl?: string; } -export type Scope = 'SCOPE_UNSPECIFIED' | 'SCOPE_MEMBER' | 'SCOPE_ALL'; +export type OrganizationTier = + | 'ORGANIZATION_TIER_UNSPECIFIED' + | 'ORGANIZATION_TIER_FREE' + | 'ORGANIZATION_TIER_ENTERPRISE'; export interface OrganizationCreateResponse { /** @@ -769,37 +736,6 @@ export interface OrganizationUpdateParams { name?: string | null; } -export interface OrganizationListParams extends OrganizationsPageParams { - /** - * Body param: pagination contains the pagination options for listing organizations - */ - pagination?: OrganizationListParams.Pagination; - - /** - * Body param: scope is the scope of the organizations to list - */ - scope?: Scope; -} - -export namespace OrganizationListParams { - /** - * pagination contains the pagination options for listing organizations - */ - export interface Pagination { - /** - * Token for the next set of results that was returned as next_token of a - * PaginationResponse - */ - token?: string; - - /** - * Page size is the maximum number of results to retrieve per page. Defaults to 25. - * Maximum 100. - */ - pageSize?: number; - } -} - export interface OrganizationDeleteParams { /** * organization_id is the ID of the organization to delete @@ -864,6 +800,7 @@ export interface OrganizationSetRoleParams { Organizations.DomainVerifications = DomainVerifications; Organizations.Invites = Invites; +Organizations.Policies = Policies; Organizations.SSOConfigurations = SSOConfigurations; export declare namespace Organizations { @@ -871,7 +808,7 @@ export declare namespace Organizations { type InviteDomains as InviteDomains, type Organization as Organization, type OrganizationMember as OrganizationMember, - type Scope as Scope, + type OrganizationTier as OrganizationTier, type OrganizationCreateResponse as OrganizationCreateResponse, type OrganizationRetrieveResponse as OrganizationRetrieveResponse, type OrganizationUpdateResponse as OrganizationUpdateResponse, @@ -879,12 +816,10 @@ export declare namespace Organizations { type OrganizationJoinResponse as OrganizationJoinResponse, type OrganizationLeaveResponse as OrganizationLeaveResponse, type OrganizationSetRoleResponse as OrganizationSetRoleResponse, - type OrganizationsOrganizationsPage as OrganizationsOrganizationsPage, type OrganizationMembersMembersPage as OrganizationMembersMembersPage, type OrganizationCreateParams as OrganizationCreateParams, type OrganizationRetrieveParams as OrganizationRetrieveParams, type OrganizationUpdateParams as OrganizationUpdateParams, - type OrganizationListParams as OrganizationListParams, type OrganizationDeleteParams as OrganizationDeleteParams, type OrganizationJoinParams as OrganizationJoinParams, type OrganizationLeaveParams as OrganizationLeaveParams, @@ -919,6 +854,15 @@ export declare namespace Organizations { type InviteGetSummaryParams as InviteGetSummaryParams, }; + export { + Policies as Policies, + type OrganizationPolicies as OrganizationPolicies, + type PolicyRetrieveResponse as PolicyRetrieveResponse, + type PolicyUpdateResponse as PolicyUpdateResponse, + type PolicyRetrieveParams as PolicyRetrieveParams, + type PolicyUpdateParams as PolicyUpdateParams, + }; + export { SSOConfigurations as SSOConfigurations, type ProviderType as ProviderType, diff --git a/src/resources/organizations/policies.ts b/src/resources/organizations/policies.ts new file mode 100644 index 0000000..468ef07 --- /dev/null +++ b/src/resources/organizations/policies.ts @@ -0,0 +1,217 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { RequestOptions } from '../../internal/request-options'; + +export class Policies extends APIResource { + /** + * Gets organization policy settings by organization ID. + * + * Use this method to: + * + * - Retrieve current policy settings for an organization + * - View resource limits and restrictions + * - Check allowed editors and other configurations + * + * ### Examples + * + * - Get organization policies: + * + * Retrieves policy settings for a specific organization. + * + * ```yaml + * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + * ``` + */ + retrieve(body: PolicyRetrieveParams, options?: RequestOptions): APIPromise { + return this._client.post('/gitpod.v1.OrganizationService/GetOrganizationPolicies', { body, ...options }); + } + + /** + * Updates organization policy settings. + * + * Use this method to: + * + * - Configure editor restrictions + * - Set environment resource limits + * - Define project creation permissions + * - Customize default configurations + * + * ### Examples + * + * - Update editor policies: + * + * Restricts available editors and sets a default. + * + * ```yaml + * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + * allowedEditorIds: + * - "vscode" + * - "jetbrains" + * defaultEditorId: "vscode" + * ``` + * + * - Set environment limits: + * + * Configures limits for environment usage. + * + * ```yaml + * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + * maximumEnvironmentTimeout: "3600s" + * maximumRunningEnvironmentsPerUser: "5" + * maximumEnvironmentsPerUser: "20" + * ``` + */ + update(body: PolicyUpdateParams, options?: RequestOptions): APIPromise { + return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganizationPolicies', { + body, + ...options, + }); + } +} + +export interface OrganizationPolicies { + /** + * allowed_editor_ids is the list of editor IDs that are allowed to be used in the + * organization + */ + allowedEditorIds: Array; + + /** + * allow_local_runners controls whether local runners are allowed to be used in the + * organization + */ + allowLocalRunners: boolean; + + /** + * default_editor_id is the default editor ID to be used when a user doesn't + * specify one + */ + defaultEditorId: string; + + /** + * default_environment_image is the default container image when none is defined in + * repo + */ + defaultEnvironmentImage: string; + + /** + * maximum_environments_per_user limits total environments (running or stopped) per + * user + */ + maximumEnvironmentsPerUser: string; + + /** + * maximum_running_environments_per_user limits simultaneously running environments + * per user + */ + maximumRunningEnvironmentsPerUser: string; + + /** + * members_create_projects controls whether members can create projects + */ + membersCreateProjects: boolean; + + /** + * members_require_projects controls whether environments can only be created from + * projects by non-admin users + */ + membersRequireProjects: boolean; + + /** + * organization_id is the ID of the organization + */ + organizationId: string; + + /** + * maximum_environment_timeout controls the maximum timeout allowed for + * environments in seconds. 0 means no limit (never). Minimum duration is 30 + * minutes. + */ + maximumEnvironmentTimeout?: string; +} + +export interface PolicyRetrieveResponse { + policies: OrganizationPolicies; +} + +export type PolicyUpdateResponse = unknown; + +export interface PolicyRetrieveParams { + /** + * organization_id is the ID of the organization to retrieve policies for + */ + organizationId: string; +} + +export interface PolicyUpdateParams { + /** + * organization_id is the ID of the organization to update policies for + */ + organizationId: string; + + /** + * allowed_editor_ids is the list of editor IDs that are allowed to be used in the + * organization + */ + allowedEditorIds?: Array; + + /** + * allow_local_runners controls whether local runners are allowed to be used in the + * organization + */ + allowLocalRunners?: boolean | null; + + /** + * default_editor_id is the default editor ID to be used when a user doesn't + * specify one + */ + defaultEditorId?: string | null; + + /** + * default_environment_image is the default container image when none is defined in + * repo + */ + defaultEnvironmentImage?: string | null; + + /** + * maximum_environments_per_user limits total environments (running or stopped) per + * user + */ + maximumEnvironmentsPerUser?: string | null; + + /** + * maximum_environment_timeout controls the maximum timeout allowed for + * environments in seconds. 0 means no limit (never). Minimum duration is 30 + * minutes. + */ + maximumEnvironmentTimeout?: string | null; + + /** + * maximum_running_environments_per_user limits simultaneously running environments + * per user + */ + maximumRunningEnvironmentsPerUser?: string | null; + + /** + * members_create_projects controls whether members can create projects + */ + membersCreateProjects?: boolean | null; + + /** + * members_require_projects controls whether environments can only be created from + * projects by non-admin users + */ + membersRequireProjects?: boolean | null; +} + +export declare namespace Policies { + export { + type OrganizationPolicies as OrganizationPolicies, + type PolicyRetrieveResponse as PolicyRetrieveResponse, + type PolicyUpdateResponse as PolicyUpdateResponse, + type PolicyRetrieveParams as PolicyRetrieveParams, + type PolicyUpdateParams as PolicyUpdateParams, + }; +} diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts index 3f3967a..27f10b3 100644 --- a/src/resources/projects/projects.ts +++ b/src/resources/projects/projects.ts @@ -293,6 +293,12 @@ export interface Project { metadata?: ProjectMetadata; + /** + * technical_description is a detailed technical description of the project This + * field is not returned by default in GetProject or ListProjects responses + */ + technicalDescription?: string; + usedBy?: Project.UsedBy; } @@ -572,6 +578,12 @@ export interface ProjectCreateParams { devcontainerFilePath?: string; name?: string; + + /** + * technical_description is a detailed technical description of the project This + * field is not returned by default in GetProject or ListProjects responses 8KB max + */ + technicalDescription?: string; } export interface ProjectRetrieveParams { @@ -615,9 +627,20 @@ export interface ProjectUpdateParams { * project_id specifies the project identifier */ projectId?: string; + + /** + * technical_description is a detailed technical description of the project This + * field is not returned by default in GetProject or ListProjects responses 8KB max + */ + technicalDescription?: string | null; } export interface ProjectListParams extends ProjectsPageParams { + /** + * Body param: + */ + filter?: ProjectListParams.Filter; + /** * Body param: pagination contains the pagination options for listing organizations */ @@ -625,6 +648,13 @@ export interface ProjectListParams extends ProjectsPageParams { } export namespace ProjectListParams { + export interface Filter { + /** + * project_ids filters the response to only projects with these IDs + */ + projectIds?: Array; + } + /** * pagination contains the pagination options for listing organizations */ diff --git a/src/resources/runners/configurations/schema.ts b/src/resources/runners/configurations/schema.ts index a7885dd..cd1222c 100644 --- a/src/resources/runners/configurations/schema.ts +++ b/src/resources/runners/configurations/schema.ts @@ -78,11 +78,39 @@ export namespace RunnerConfigurationSchema { } export interface Enum { + /** + * @deprecated deprecated, will be removed, use default_value instead + */ default?: string; + defaultValue?: Enum.DefaultValue; + + possibleValues?: Array; + + /** + * @deprecated deprecated, will be removed, use possible_values instead + */ values?: Array; } + export namespace Enum { + export interface DefaultValue { + detail?: string; + + subtitle?: string; + + title?: string; + } + + export interface PossibleValue { + detail?: string; + + subtitle?: string; + + title?: string; + } + } + export interface Int { default?: number; @@ -130,11 +158,39 @@ export namespace RunnerConfigurationSchema { } export interface Enum { + /** + * @deprecated deprecated, will be removed, use default_value instead + */ default?: string; + defaultValue?: Enum.DefaultValue; + + possibleValues?: Array; + + /** + * @deprecated deprecated, will be removed, use possible_values instead + */ values?: Array; } + export namespace Enum { + export interface DefaultValue { + detail?: string; + + subtitle?: string; + + title?: string; + } + + export interface PossibleValue { + detail?: string; + + subtitle?: string; + + title?: string; + } + } + export interface Int { default?: number; diff --git a/src/resources/runners/index.ts b/src/resources/runners/index.ts index 4534266..0f5a99a 100644 --- a/src/resources/runners/index.ts +++ b/src/resources/runners/index.ts @@ -23,6 +23,8 @@ export { } from './policies'; export { Runners, + type LogLevel, + type MetricsConfiguration, type Runner, type RunnerCapability, type RunnerConfiguration, diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts index 0925d50..223f884 100644 --- a/src/resources/runners/runners.ts +++ b/src/resources/runners/runners.ts @@ -288,6 +288,35 @@ export class Runners extends APIResource { export type RunnersRunnersPage = RunnersPage; +export type LogLevel = + | 'LOG_LEVEL_UNSPECIFIED' + | 'LOG_LEVEL_DEBUG' + | 'LOG_LEVEL_INFO' + | 'LOG_LEVEL_WARN' + | 'LOG_LEVEL_ERROR'; + +export interface MetricsConfiguration { + /** + * enabled indicates whether the runner should collect metrics + */ + enabled?: boolean; + + /** + * password is the password to use for the metrics collector + */ + password?: string; + + /** + * url is the URL of the metrics collector + */ + url?: string; + + /** + * username is the username to use for the metrics collector + */ + username?: string; +} + export interface Runner { /** * Time when the Runner was created. @@ -335,7 +364,10 @@ export interface Runner { export type RunnerCapability = | 'RUNNER_CAPABILITY_UNSPECIFIED' | 'RUNNER_CAPABILITY_FETCH_LOCAL_SCM_INTEGRATIONS' - | 'RUNNER_CAPABILITY_SECRET_CONTAINER_REGISTRY'; + | 'RUNNER_CAPABILITY_SECRET_CONTAINER_REGISTRY' + | 'RUNNER_CAPABILITY_AGENT_EXECUTION' + | 'RUNNER_CAPABILITY_ALLOW_ENV_TOKEN_POPULATION' + | 'RUNNER_CAPABILITY_DEFAULT_DEV_CONTAINER_IMAGE'; export interface RunnerConfiguration { /** @@ -343,6 +375,16 @@ export interface RunnerConfiguration { */ autoUpdate?: boolean; + /** + * log_level is the log level for the runner + */ + logLevel?: LogLevel; + + /** + * metrics contains configuration for the runner's metrics collection + */ + metrics?: MetricsConfiguration; + /** * Region to deploy the runner in, if applicable. This is mainly used for remote * runners, and is only a hint. The runner may be deployed in a different region. @@ -570,6 +612,11 @@ export interface RunnerParseContextURLResponse { git?: RunnerParseContextURLResponse.Git; originalContextUrl?: string; + + /** + * project_ids is a list of projects to which the context URL belongs to. + */ + projectIds?: Array; } export namespace RunnerParseContextURLResponse { @@ -658,11 +705,48 @@ export namespace RunnerUpdateParams { */ autoUpdate?: boolean | null; + /** + * log_level is the log level for the runner + */ + logLevel?: RunnersAPI.LogLevel | null; + + /** + * metrics contains configuration for the runner's metrics collection + */ + metrics?: Configuration.Metrics | null; + /** * The release channel the runner is on */ releaseChannel?: RunnersAPI.RunnerReleaseChannel | null; } + + export namespace Configuration { + /** + * metrics contains configuration for the runner's metrics collection + */ + export interface Metrics { + /** + * enabled indicates whether the runner should collect metrics + */ + enabled?: boolean | null; + + /** + * password is the password to use for the metrics collector + */ + password?: string | null; + + /** + * url is the URL of the metrics collector + */ + url?: string | null; + + /** + * username is the username to use for the metrics collector + */ + username?: string | null; + } + } } } @@ -747,6 +831,8 @@ Runners.Policies = Policies; export declare namespace Runners { export { + type LogLevel as LogLevel, + type MetricsConfiguration as MetricsConfiguration, type Runner as Runner, type RunnerCapability as RunnerCapability, type RunnerConfiguration as RunnerConfiguration, diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts index 62ceb78..f6a9e38 100644 --- a/src/resources/secrets.ts +++ b/src/resources/secrets.ts @@ -1,6 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../core/resource'; +import * as SecretsAPI from './secrets'; import * as Shared from './shared'; import { APIPromise } from '../core/api-promise'; import { PagePromise, SecretsPage, type SecretsPageParams } from '../core/pagination'; @@ -57,25 +58,7 @@ export class Secrets extends APIResource { } /** - * Lists secrets with optional filtering. - * - * Use this method to: - * - * - View all project secrets - * - Filter secrets by project - * - * ### Examples - * - * - List project secrets: - * - * Shows all secrets for a project. - * - * ```yaml - * filter: - * projectIds: ["b0e12f6c-4c67-429d-a4a6-d9838b5da047"] - * pagination: - * pageSize: 20 - * ``` + * ListSecrets */ list(params: SecretListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -280,10 +263,12 @@ export interface Secret { name?: string; /** - * The Project ID this Secret belongs to + * @deprecated The Project ID this Secret belongs to Deprecated: use scope instead */ projectId?: string; + scope?: SecretScope; + /** * A Timestamp represents a point in time independent of any time zone or local * calendar, encoded as a count of seconds and fractions of seconds at nanosecond @@ -377,6 +362,18 @@ export interface Secret { updatedAt?: string; } +export interface SecretScope { + /** + * project_id is the Project ID this Secret belongs to + */ + projectId?: string; + + /** + * user_id is the User ID this Secret belongs to + */ + userId?: string; +} + export interface SecretCreateResponse { secret?: Secret; } @@ -392,12 +389,7 @@ export type SecretUpdateValueResponse = unknown; export interface SecretCreateParams { /** * secret will be mounted as a docker config in the environment VM, mount will have - * the docker registry host value must be a valid registry host (e.g. - * registry.docker.com, https://registry.docker.com, ghcr.io:5050): - * - * ``` - * this.matches('^[a-zA-Z0-9.-/:]+(:[0-9]+)?$') - * ``` + * the docker registry host */ containerRegistryBasicAuthHost?: string; @@ -420,10 +412,16 @@ export interface SecretCreateParams { name?: string; /** - * project_id is the ProjectID this Secret belongs to + * @deprecated project_id is the ProjectID this Secret belongs to Deprecated: use + * scope instead */ projectId?: string; + /** + * scope is the scope of the secret + */ + scope?: SecretScope; + /** * value is the plaintext value of the secret */ @@ -445,9 +443,16 @@ export interface SecretListParams extends SecretsPageParams { export namespace SecretListParams { export interface Filter { /** - * project_ids filters the response to only Secrets used by these Project IDs + * @deprecated project_ids filters the response to only Secrets used by these + * Project IDs Deprecated: use scope instead. Values in project_ids will be + * ignored. */ projectIds?: Array; + + /** + * scope is the scope of the secrets to list + */ + scope?: SecretsAPI.SecretScope; } /** @@ -488,6 +493,7 @@ export interface SecretUpdateValueParams { export declare namespace Secrets { export { type Secret as Secret, + type SecretScope as SecretScope, type SecretCreateResponse as SecretCreateResponse, type SecretDeleteResponse as SecretDeleteResponse, type SecretGetValueResponse as SecretGetValueResponse, diff --git a/src/resources/shared.ts b/src/resources/shared.ts index b771f1d..d2f7c17 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -280,6 +280,12 @@ export namespace TaskExecutionStatus { */ failureMessage?: string; + /** + * output contains the output of the task execution. setting an output field to + * empty string will unset it. + */ + output?: Record; + /** * phase is the current phase of the execution step */ diff --git a/src/resources/users/dotfiles.ts b/src/resources/users/dotfiles.ts new file mode 100644 index 0000000..7a69609 --- /dev/null +++ b/src/resources/users/dotfiles.ts @@ -0,0 +1,89 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { RequestOptions } from '../../internal/request-options'; + +export class Dotfiles extends APIResource { + /** + * Gets the dotfiles for a user. + * + * Use this method to: + * + * - Retrieve user dotfiles + * + * ### Examples + * + * - Get dotfiles: + * + * Retrieves the dotfiles for the current user. + * + * ```yaml + * {} + * ``` + */ + get(body: DotfileGetParams, options?: RequestOptions): APIPromise { + return this._client.post('/gitpod.v1.UserService/GetDotfilesConfiguration', { body, ...options }); + } + + /** + * Sets the dotfiles configuration for a user. + * + * Use this method to: + * + * - Configure user dotfiles + * - Update dotfiles settings + * + * ### Examples + * + * - Set dotfiles configuration: + * + * Sets the dotfiles configuration for the current user. + * + * ```yaml + * { "repository": "https://github.com/gitpod-io/dotfiles" } + * ``` + * + * - Remove dotfiles: + * + * Removes the dotfiles for the current user. + * + * ```yaml + * {} + * ``` + */ + set(body: DotfileSetParams, options?: RequestOptions): APIPromise { + return this._client.post('/gitpod.v1.UserService/SetDotfilesConfiguration', { body, ...options }); + } +} + +export interface DotfilesConfiguration { + /** + * The URL of a dotfiles repository. + */ + repository?: string; +} + +export interface DotfileGetResponse { + dotfilesConfiguration: DotfilesConfiguration; +} + +export type DotfileSetResponse = unknown; + +export interface DotfileGetParams { + empty?: boolean; +} + +export interface DotfileSetParams { + repository?: string; +} + +export declare namespace Dotfiles { + export { + type DotfilesConfiguration as DotfilesConfiguration, + type DotfileGetResponse as DotfileGetResponse, + type DotfileSetResponse as DotfileSetResponse, + type DotfileGetParams as DotfileGetParams, + type DotfileSetParams as DotfileSetParams, + }; +} diff --git a/src/resources/users/index.ts b/src/resources/users/index.ts index 159e1d4..c91cbf0 100644 --- a/src/resources/users/index.ts +++ b/src/resources/users/index.ts @@ -1,5 +1,13 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +export { + Dotfiles, + type DotfilesConfiguration, + type DotfileGetResponse, + type DotfileSetResponse, + type DotfileGetParams, + type DotfileSetParams, +} from './dotfiles'; export { Pats, type PersonalAccessToken, diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts index 4fb4bad..07f8eca 100644 --- a/src/resources/users/users.ts +++ b/src/resources/users/users.ts @@ -2,6 +2,15 @@ import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; +import * as DotfilesAPI from './dotfiles'; +import { + DotfileGetParams, + DotfileGetResponse, + DotfileSetParams, + DotfileSetResponse, + Dotfiles, + DotfilesConfiguration, +} from './dotfiles'; import * as PatsAPI from './pats'; import { PatDeleteParams, @@ -17,6 +26,7 @@ import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; export class Users extends APIResource { + dotfiles: DotfilesAPI.Dotfiles = new DotfilesAPI.Dotfiles(this._client); pats: PatsAPI.Pats = new PatsAPI.Pats(this._client); /** @@ -130,6 +140,7 @@ export interface UserSetSuspendedParams { userId?: string; } +Users.Dotfiles = Dotfiles; Users.Pats = Pats; export declare namespace Users { @@ -141,6 +152,15 @@ export declare namespace Users { type UserSetSuspendedParams as UserSetSuspendedParams, }; + export { + Dotfiles as Dotfiles, + type DotfilesConfiguration as DotfilesConfiguration, + type DotfileGetResponse as DotfileGetResponse, + type DotfileSetResponse as DotfileSetResponse, + type DotfileGetParams as DotfileGetParams, + type DotfileSetParams as DotfileSetParams, + }; + export { Pats as Pats, type PersonalAccessToken as PersonalAccessToken, diff --git a/tests/api-resources/environments/environments.test.ts b/tests/api-resources/environments/environments.test.ts index 22b33f8..aaf1efc 100644 --- a/tests/api-resources/environments/environments.test.ts +++ b/tests/api-resources/environments/environments.test.ts @@ -77,6 +77,27 @@ describe('resource environments', () => { expect(dataAndResponse.response).toBe(rawResponse); }); + // skipped: tests are disabled for the time being + test.skip('createEnvironmentToken: only required params', async () => { + const responsePromise = client.environments.createEnvironmentToken({ + environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // skipped: tests are disabled for the time being + test.skip('createEnvironmentToken: required and optional params', async () => { + const response = await client.environments.createEnvironmentToken({ + environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + }); + }); + // skipped: tests are disabled for the time being test.skip('createFromProject', async () => { const responsePromise = client.environments.createFromProject({}); diff --git a/tests/api-resources/organizations/organizations.test.ts b/tests/api-resources/organizations/organizations.test.ts index 16be6a5..09fc8b7 100644 --- a/tests/api-resources/organizations/organizations.test.ts +++ b/tests/api-resources/organizations/organizations.test.ts @@ -73,18 +73,6 @@ describe('resource organizations', () => { }); }); - // skipped: tests are disabled for the time being - test.skip('list', async () => { - const responsePromise = client.organizations.list({}); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - // skipped: tests are disabled for the time being test.skip('delete: only required params', async () => { const responsePromise = client.organizations.delete({ diff --git a/tests/api-resources/organizations/policies.test.ts b/tests/api-resources/organizations/policies.test.ts new file mode 100644 index 0000000..a0aba22 --- /dev/null +++ b/tests/api-resources/organizations/policies.test.ts @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Gitpod from '@gitpod/sdk'; + +const client = new Gitpod({ + bearerToken: 'My Bearer Token', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource policies', () => { + // skipped: tests are disabled for the time being + test.skip('retrieve: only required params', async () => { + const responsePromise = client.organizations.policies.retrieve({ + organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // skipped: tests are disabled for the time being + test.skip('retrieve: required and optional params', async () => { + const response = await client.organizations.policies.retrieve({ + organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + }); + }); + + // skipped: tests are disabled for the time being + test.skip('update: only required params', async () => { + const responsePromise = client.organizations.policies.update({ + organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // skipped: tests are disabled for the time being + test.skip('update: required and optional params', async () => { + const response = await client.organizations.policies.update({ + organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + allowedEditorIds: ['string'], + allowLocalRunners: true, + defaultEditorId: 'defaultEditorId', + defaultEnvironmentImage: 'defaultEnvironmentImage', + maximumEnvironmentsPerUser: '20', + maximumEnvironmentTimeout: '3600s', + maximumRunningEnvironmentsPerUser: '5', + membersCreateProjects: true, + membersRequireProjects: true, + }); + }); +}); diff --git a/tests/api-resources/projects/projects.test.ts b/tests/api-resources/projects/projects.test.ts index 1ad8e40..b30ee89 100644 --- a/tests/api-resources/projects/projects.test.ts +++ b/tests/api-resources/projects/projects.test.ts @@ -41,6 +41,7 @@ describe('resource projects', () => { automationsFilePath: 'automationsFilePath', devcontainerFilePath: 'devcontainerFilePath', name: 'Web Application', + technicalDescription: 'technicalDescription', }); }); diff --git a/tests/api-resources/users/dotfiles.test.ts b/tests/api-resources/users/dotfiles.test.ts new file mode 100644 index 0000000..5694cb1 --- /dev/null +++ b/tests/api-resources/users/dotfiles.test.ts @@ -0,0 +1,34 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Gitpod from '@gitpod/sdk'; + +const client = new Gitpod({ + bearerToken: 'My Bearer Token', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource dotfiles', () => { + // skipped: tests are disabled for the time being + test.skip('get', async () => { + const responsePromise = client.users.dotfiles.get({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // skipped: tests are disabled for the time being + test.skip('set', async () => { + const responsePromise = client.users.dotfiles.set({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); +}); From f0edc9696d24e0a4e4ed648b585883616cde251f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 09:52:40 +0000 Subject: [PATCH 42/46] feat(api): manual updates --- .stats.yml | 4 +- api.md | 10 +++ src/client.ts | 20 +++++ src/core/pagination.ts | 55 ++++++++++++ src/resources/index.ts | 6 ++ src/resources/usage.ts | 140 ++++++++++++++++++++++++++++++ tests/api-resources/usage.test.ts | 22 +++++ 7 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 src/resources/usage.ts create mode 100644 tests/api-resources/usage.test.ts diff --git a/.stats.yml b/.stats.yml index ef4c630..5233e38 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 115 +configured_endpoints: 116 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d -config_hash: 981e43e8b1e3ddabd435d350aeeed417 +config_hash: 60929489bdc1eaf979e7ef74fdd17b94 diff --git a/api.md b/api.md index 82689ae..516cda9 100644 --- a/api.md +++ b/api.md @@ -484,6 +484,16 @@ Methods: - client.secrets.getValue({ ...params }) -> SecretGetValueResponse - client.secrets.updateValue({ ...params }) -> unknown +# Usage + +Types: + +- EnvironmentSession + +Methods: + +- client.usage.listEnvironmentSessions({ ...params }) -> EnvironmentSessionsSessionsPage + # Users Types: diff --git a/src/client.ts b/src/client.ts index e9880cc..d7e3523 100644 --- a/src/client.ts +++ b/src/client.ts @@ -49,6 +49,8 @@ import { SecretsPageResponse, type ServicesPageParams, ServicesPageResponse, + type SessionsPageParams, + SessionsPageResponse, type TaskExecutionsPageParams, TaskExecutionsPageResponse, type TasksPageParams, @@ -123,6 +125,12 @@ import { Secrets, SecretsSecretsPage, } from './resources/secrets'; +import { + EnvironmentSession, + EnvironmentSessionsSessionsPage, + Usage, + UsageListEnvironmentSessionsParams, +} from './resources/usage'; import { readEnv } from './internal/utils/env'; import { formatRequestDetails, loggerFor } from './internal/utils/log'; import { isEmptyObj } from './internal/utils/values'; @@ -917,6 +925,7 @@ export class Gitpod { projects: API.Projects = new API.Projects(this); runners: API.Runners = new API.Runners(this); secrets: API.Secrets = new API.Secrets(this); + usage: API.Usage = new API.Usage(this); users: API.Users = new API.Users(this); } Gitpod.Accounts = Accounts; @@ -929,6 +938,7 @@ Gitpod.Organizations = Organizations; Gitpod.Projects = Projects; Gitpod.Runners = Runners; Gitpod.Secrets = Secrets; +Gitpod.Usage = Usage; Gitpod.Users = Users; export declare namespace Gitpod { export type RequestOptions = Opts.RequestOptions; @@ -996,6 +1006,9 @@ export declare namespace Gitpod { export import ServicesPage = Pagination.ServicesPage; export { type ServicesPageParams as ServicesPageParams, type ServicesPageResponse as ServicesPageResponse }; + export import SessionsPage = Pagination.SessionsPage; + export { type SessionsPageParams as SessionsPageParams, type SessionsPageResponse as SessionsPageResponse }; + export import SSOConfigurationsPage = Pagination.SSOConfigurationsPage; export { type SSOConfigurationsPageParams as SSOConfigurationsPageParams, @@ -1194,6 +1207,13 @@ export declare namespace Gitpod { type SecretUpdateValueParams as SecretUpdateValueParams, }; + export { + Usage as Usage, + type EnvironmentSession as EnvironmentSession, + type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage, + type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams, + }; + export { Users as Users, type User as User, diff --git a/src/core/pagination.ts b/src/core/pagination.ts index 250b4fc..f72f6ff 100644 --- a/src/core/pagination.ts +++ b/src/core/pagination.ts @@ -941,6 +941,61 @@ export class ServicesPage extends AbstractPage implements ServicesPa } } +export interface SessionsPageResponse { + pagination: SessionsPageResponse.Pagination; + + sessions: Array; +} + +export namespace SessionsPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface SessionsPageParams { + pageSize?: number; + + token?: string; +} + +export class SessionsPage extends AbstractPage implements SessionsPageResponse { + pagination: SessionsPageResponse.Pagination; + + sessions: Array; + + constructor( + client: Gitpod, + response: Response, + body: SessionsPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.pagination = body.pagination || {}; + this.sessions = body.sessions || []; + } + + getPaginatedItems(): Item[] { + return this.sessions ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + export interface SSOConfigurationsPageResponse { pagination: SSOConfigurationsPageResponse.Pagination; diff --git a/src/resources/index.ts b/src/resources/index.ts index be1edca..664e230 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -166,6 +166,12 @@ export { type SecretUpdateValueParams, type SecretsSecretsPage, } from './secrets'; +export { + Usage, + type EnvironmentSession, + type UsageListEnvironmentSessionsParams, + type EnvironmentSessionsSessionsPage, +} from './usage'; export { Users, type User, diff --git a/src/resources/usage.ts b/src/resources/usage.ts new file mode 100644 index 0000000..c648e2c --- /dev/null +++ b/src/resources/usage.ts @@ -0,0 +1,140 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../core/resource'; +import { PagePromise, SessionsPage, type SessionsPageParams } from '../core/pagination'; +import { RequestOptions } from '../internal/request-options'; + +export class Usage extends APIResource { + /** + * Lists environment sessions within a specified date range. + * + * Returns a list of environment sessions that were active within the specified + * date range. + */ + listEnvironmentSessions( + params: UsageListEnvironmentSessionsParams, + options?: RequestOptions, + ): PagePromise { + const { token, pageSize, ...body } = params; + return this._client.getAPIList( + '/gitpod.v1.UsageService/ListEnvironmentSessions', + SessionsPage, + { query: { token, pageSize }, body, method: 'post', ...options }, + ); + } +} + +export type EnvironmentSessionsSessionsPage = SessionsPage; + +export interface EnvironmentSession { + /** + * Environment session ID. + */ + id?: string; + + /** + * Time when the session was created. + */ + createdAt?: string; + + /** + * Environment class ID associated with the session. + */ + environmentClassId?: string; + + /** + * Environment ID associated with the session. + */ + environmentId?: string; + + /** + * Project ID associated with the session. + */ + projectId?: string; + + /** + * Runner ID associated with the session. + */ + runnerId?: string; + + /** + * Time when the session was stopped. + */ + stoppedAt?: string; + + /** + * User ID who created the session. + */ + userId?: string; +} + +export interface UsageListEnvironmentSessionsParams extends SessionsPageParams { + /** + * Body param: Filter options. + */ + filter?: UsageListEnvironmentSessionsParams.Filter; + + /** + * Body param: Pagination options. + */ + pagination?: UsageListEnvironmentSessionsParams.Pagination; +} + +export namespace UsageListEnvironmentSessionsParams { + /** + * Filter options. + */ + export interface Filter { + /** + * Date range to query sessions within. + */ + dateRange: Filter.DateRange; + + /** + * Optional project ID to filter sessions by. + */ + projectId?: string; + } + + export namespace Filter { + /** + * Date range to query sessions within. + */ + export interface DateRange { + /** + * End time of the date range (exclusive). + */ + endTime: string; + + /** + * Start time of the date range (inclusive). + */ + startTime: string; + } + } + + /** + * Pagination options. + */ + export interface Pagination { + /** + * Token for the next set of results that was returned as next_token of a + * PaginationResponse + */ + token?: string; + + /** + * Page size is the maximum number of results to retrieve per page. Defaults to 25. + * Maximum 100. + */ + pageSize?: number; + } +} + +export declare namespace Usage { + export { + type EnvironmentSession as EnvironmentSession, + type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage, + type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams, + }; +} diff --git a/tests/api-resources/usage.test.ts b/tests/api-resources/usage.test.ts new file mode 100644 index 0000000..1d2b3dc --- /dev/null +++ b/tests/api-resources/usage.test.ts @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Gitpod from '@gitpod/sdk'; + +const client = new Gitpod({ + bearerToken: 'My Bearer Token', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource usage', () => { + // skipped: tests are disabled for the time being + test.skip('listEnvironmentSessions', async () => { + const responsePromise = client.usage.listEnvironmentSessions({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); +}); From 77b6f44b695808f66ce955683f86965c3b8605fb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 10:19:57 +0000 Subject: [PATCH 43/46] feat(api): manual updates --- .stats.yml | 4 ++-- src/resources/runners/runners.ts | 13 +++++++++++++ src/resources/secrets.ts | 33 +++++++++++++++++++++++++++++++- src/resources/usage.ts | 29 +++++++++++++++++++++++----- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5233e38..9cdc117 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 116 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml -openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2e6ddfc9da00e33fcf13baf0b67012b97f051fa986658ff114fde989e56caa94.yml +openapi_spec_hash: 5af02ea2008312d609394e548756e761 config_hash: 60929489bdc1eaf979e7ef74fdd17b94 diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts index 223f884..5abb6dd 100644 --- a/src/resources/runners/runners.ts +++ b/src/resources/runners/runners.ts @@ -375,6 +375,13 @@ export interface RunnerConfiguration { */ autoUpdate?: boolean; + /** + * devcontainer_image_cache_enabled controls whether the devcontainer build cache + * is enabled for this runner. Only takes effect on supported runners, currently + * only AWS EC2 runners. + */ + devcontainerImageCacheEnabled?: boolean; + /** * log_level is the log level for the runner */ @@ -705,6 +712,12 @@ export namespace RunnerUpdateParams { */ autoUpdate?: boolean | null; + /** + * devcontainer_image_cache_enabled controls whether the shared devcontainer build + * cache is enabled for this runner. + */ + devcontainerImageCacheEnabled?: boolean | null; + /** * log_level is the log level for the runner */ diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts index f6a9e38..68c387d 100644 --- a/src/resources/secrets.ts +++ b/src/resources/secrets.ts @@ -58,7 +58,38 @@ export class Secrets extends APIResource { } /** - * ListSecrets + * Lists secrets + * + * Use this method to: + * + * - View all project secrets + * - View all user secrets + * + * ### Examples + * + * - List project secrets: + * + * Shows all secrets for a project. + * + * ```yaml + * filter: + * scope: + * projectId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + * pagination: + * pageSize: 20 + * ``` + * + * - List user secrets: + * + * Shows all secrets for a user. + * + * ```yaml + * filter: + * scope: + * userId: "123e4567-e89b-12d3-a456-426614174000" + * pagination: + * pageSize: 20 + * ``` */ list(params: SecretListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; diff --git a/src/resources/usage.ts b/src/resources/usage.ts index c648e2c..9417a8f 100644 --- a/src/resources/usage.ts +++ b/src/resources/usage.ts @@ -6,10 +6,29 @@ import { RequestOptions } from '../internal/request-options'; export class Usage extends APIResource { /** - * Lists environment sessions within a specified date range. + * Lists completed environment sessions within a specified date range. * - * Returns a list of environment sessions that were active within the specified - * date range. + * Returns a list of environment sessions that were completed within the specified + * date range. Currently running sessions are not included. + * + * Use this method to: + * + * - View environment sessions + * - Filter by project + * - Monitor session activity + * - Create custom usage reports + * + * ### Example + * + * ```yaml + * filter: + * projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + * dateRange: + * startTime: "2024-01-01T00:00:00Z" + * endTime: "2024-01-02T00:00:00Z" + * pagination: + * pageSize: 100 + * ``` */ listEnvironmentSessions( params: UsageListEnvironmentSessionsParams, @@ -48,7 +67,7 @@ export interface EnvironmentSession { environmentId?: string; /** - * Project ID associated with the session. + * Project ID associated with the session (if available). */ projectId?: string; @@ -63,7 +82,7 @@ export interface EnvironmentSession { stoppedAt?: string; /** - * User ID who created the session. + * User ID that created the session. */ userId?: string; } From 078548f4b1cd2101e258bd27c5c0fd5628566a88 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:00:04 +0000 Subject: [PATCH 44/46] feat(api): manual updates --- .github/workflows/ci.yml | 6 +- .github/workflows/publish-npm.yml | 2 +- .stats.yml | 8 +- README.md | 2 +- SECURITY.md | 4 +- api.md | 16 +- bin/publish-npm | 30 ++- eslint.config.mjs | 2 +- jest.config.ts | 1 + package.json | 9 +- src/client.ts | 60 ++++-- src/core/pagination.ts | 143 ++++++++++----- src/internal/detect-platform.ts | 6 +- src/internal/headers.ts | 2 +- src/internal/shims/crypto.ts | 18 -- src/internal/shims/file.ts | 32 ---- src/internal/shims/getBuiltinModule.ts | 66 ------- src/internal/shims/nullGetBuiltinModule.ts | 1 - src/internal/to-file.ts | 6 +- src/internal/uploads.ts | 20 +- src/internal/utils/uuid.ts | 4 +- src/resources/accounts.ts | 92 ++++++++++ src/resources/editors.ts | 26 +++ .../environments/automations/automations.ts | 29 +++ .../environments/automations/services.ts | 79 ++++++++ .../automations/tasks/executions.ts | 34 ++++ .../environments/automations/tasks/tasks.ts | 61 +++++++ src/resources/environments/classes.ts | 8 + src/resources/environments/environments.ts | 171 ++++++++++++++++++ src/resources/environments/index.ts | 2 + src/resources/events.ts | 19 ++ src/resources/gateways.ts | 57 ++++++ src/resources/groups.ts | 10 + src/resources/identity.ts | 23 +++ src/resources/index.ts | 12 +- .../organizations/domain-verifications.ts | 49 +++++ src/resources/organizations/invites.ts | 22 +++ src/resources/organizations/organizations.ts | 66 +++++++ src/resources/organizations/policies.ts | 31 ++++ .../organizations/sso-configurations.ts | 55 ++++++ src/resources/projects/policies.ts | 39 ++++ src/resources/projects/projects.ts | 60 ++++++ .../runners/configurations/configurations.ts | 21 +++ .../configurations/environment-classes.ts | 54 ++++++ .../host-authentication-tokens.ts | 60 ++++++ .../runners/configurations/schema.ts | 8 + .../configurations/scm-integrations.ts | 77 ++++++++ src/resources/runners/index.ts | 1 + src/resources/runners/policies.ts | 39 ++++ src/resources/runners/runners.ts | 106 ++++++++++- src/resources/secrets.ts | 47 +++++ src/resources/shared.ts | 28 ++- src/resources/usage.ts | 85 +++++---- src/resources/users/dotfiles.ts | 10 + src/resources/users/pats.ts | 31 ++++ src/resources/users/users.ts | 12 ++ tests/api-resources/accounts.test.ts | 12 ++ .../environments/environments.test.ts | 12 ++ tests/api-resources/gateways.test.ts | 22 +++ .../organizations/policies.test.ts | 1 + tests/api-resources/usage.test.ts | 4 +- tests/index.test.ts | 76 ++++++++ yarn.lock | 34 ++-- 63 files changed, 1849 insertions(+), 274 deletions(-) delete mode 100644 src/internal/shims/crypto.ts delete mode 100644 src/internal/shims/file.ts delete mode 100644 src/internal/shims/getBuiltinModule.ts delete mode 100644 src/internal/shims/nullGetBuiltinModule.ts create mode 100644 src/resources/gateways.ts create mode 100644 tests/api-resources/gateways.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c21a27..90365fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap @@ -40,7 +40,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap @@ -72,7 +72,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index d11b246..9d34b14 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@v3 with: - node-version: '18' + node-version: '20' - name: Install dependencies run: | diff --git a/.stats.yml b/.stats.yml index 9cdc117..ac7c24e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 116 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2e6ddfc9da00e33fcf13baf0b67012b97f051fa986658ff114fde989e56caa94.yml -openapi_spec_hash: 5af02ea2008312d609394e548756e761 -config_hash: 60929489bdc1eaf979e7ef74fdd17b94 +configured_endpoints: 119 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c850a6432597255fc1b788ba21a0494162e639f41dd80c0f9d07def239d31865.yml +openapi_spec_hash: fba3f62e51d3ba39eea280abe29f39f1 +config_hash: 8e3b8fba844b78950ad4a13b75b7fffc diff --git a/README.md b/README.md index a2f50c6..2121f11 100644 --- a/README.md +++ b/README.md @@ -386,7 +386,7 @@ TypeScript >= 4.9 is supported. The following runtimes are supported: - Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more) -- Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions. +- Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions. - Deno v1.28.0 or higher. - Bun 1.0 or later. - Cloudflare Workers. diff --git a/SECURITY.md b/SECURITY.md index 2b0ed90..efd9088 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,11 +16,11 @@ before making any information public. ## Reporting Non-SDK Related Security Issues If you encounter security issues that are not directly related to SDKs but pertain to the services -or products provided by Gitpod please follow the respective company's security reporting guidelines. +or products provided by Gitpod, please follow the respective company's security reporting guidelines. ### Gitpod Terms and Policies -Please contact dev-feedback@gitpod.com for any questions or concerns regarding security of our services. +Please contact dev-feedback@gitpod.com for any questions or concerns regarding the security of our services. --- diff --git a/api.md b/api.md index 516cda9..228b9e2 100644 --- a/api.md +++ b/api.md @@ -6,6 +6,7 @@ Types: - EnvironmentClass - ErrorCode - FieldValue +- Gateway - OrganizationRole - Principal - RunsOn @@ -31,12 +32,14 @@ Types: - AccountRetrieveResponse - AccountDeleteResponse - AccountGetSSOLoginURLResponse +- AccountListJoinableOrganizationsResponse Methods: - client.accounts.retrieve({ ...params }) -> AccountRetrieveResponse - client.accounts.delete({ ...params }) -> unknown - client.accounts.getSSOLoginURL({ ...params }) -> AccountGetSSOLoginURLResponse +- client.accounts.listJoinableOrganizations({ ...params }) -> AccountListJoinableOrganizationsResponse - client.accounts.listLoginProviders({ ...params }) -> LoginProvidersLoginProvidersPage # Editors @@ -74,6 +77,7 @@ Types: - EnvironmentMarkActiveResponse - EnvironmentStartResponse - EnvironmentStopResponse +- EnvironmentUnarchiveResponse Methods: @@ -88,6 +92,7 @@ Methods: - client.environments.markActive({ ...params }) -> unknown - client.environments.start({ ...params }) -> unknown - client.environments.stop({ ...params }) -> unknown +- client.environments.unarchive({ ...params }) -> unknown ## Automations @@ -178,6 +183,12 @@ Methods: - client.events.list({ ...params }) -> EventListResponsesEntriesPage - client.events.watch({ ...params }) -> EventWatchResponse +# Gateways + +Methods: + +- client.gateways.list({ ...params }) -> GatewaysGatewaysPage + # Groups Types: @@ -341,6 +352,7 @@ Methods: Types: +- GatewayInfo - LogLevel - MetricsConfiguration - Runner @@ -488,11 +500,11 @@ Methods: Types: -- EnvironmentSession +- EnvironmentUsageRecord Methods: -- client.usage.listEnvironmentSessions({ ...params }) -> EnvironmentSessionsSessionsPage +- client.usage.listEnvironmentRuntimeRecords({ ...params }) -> EnvironmentUsageRecordsRecordsPage # Users diff --git a/bin/publish-npm b/bin/publish-npm index 4c21181..2505dec 100644 --- a/bin/publish-npm +++ b/bin/publish-npm @@ -4,19 +4,35 @@ set -eux npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN" -# Build the project yarn build - -# Navigate to the dist directory cd dist -# Get the version from package.json +# Get latest version from npm +# +# If the package doesn't exist, yarn will return +# {"type":"error","data":"Received invalid response from npm."} +# where .data.version doesn't exist so LAST_VERSION will be an empty string. +LAST_VERSION="$(yarn info --json 2> /dev/null | jq -r '.data.version')" + +# Get current version from package.json VERSION="$(node -p "require('./package.json').version")" -# Extract the pre-release tag if it exists +# Check if current version is pre-release (e.g. alpha / beta / rc) +CURRENT_IS_PRERELEASE=false if [[ "$VERSION" =~ -([a-zA-Z]+) ]]; then - # Extract the part before any dot in the pre-release identifier - TAG="${BASH_REMATCH[1]}" + CURRENT_IS_PRERELEASE=true + CURRENT_TAG="${BASH_REMATCH[1]}" +fi + +# Check if last version is a stable release +LAST_IS_STABLE_RELEASE=true +if [[ -z "$LAST_VERSION" || "$LAST_VERSION" =~ -([a-zA-Z]+) ]]; then + LAST_IS_STABLE_RELEASE=false +fi + +# Use a corresponding alpha/beta tag if there already is a stable release and we're publishing a prerelease. +if $CURRENT_IS_PRERELEASE && $LAST_IS_STABLE_RELEASE; then + TAG="$CURRENT_TAG" else TAG="latest" fi diff --git a/eslint.config.mjs b/eslint.config.mjs index bd8e0cb..a73ce38 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -10,7 +10,7 @@ export default tseslint.config( parserOptions: { sourceType: 'module' }, }, files: ['**/*.ts', '**/*.mts', '**/*.cts', '**/*.js', '**/*.mjs', '**/*.cjs'], - ignores: ['dist/**'], + ignores: ['dist/'], plugins: { '@typescript-eslint': tseslint.plugin, 'unused-imports': unusedImports, diff --git a/jest.config.ts b/jest.config.ts index d185444..7b14a51 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -15,6 +15,7 @@ const config: JestConfigWithTsJest = { '/dist/', '/deno/', '/deno_tests/', + '/packages/', ], testPathIgnorePatterns: ['scripts'], }; diff --git a/package.json b/package.json index 615f6e6..8b673e5 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/parser": "8.31.1", "eslint": "^9.20.1", - "eslint-plugin-prettier": "^5.2.3", + "eslint-plugin-prettier": "^5.4.1", "eslint-plugin-unused-imports": "^4.1.4", "iconv-lite": "^0.6.3", "jest": "^29.4.0", @@ -50,13 +50,6 @@ "typescript": "5.8.3", "typescript-eslint": "8.31.1" }, - "resolutions": { - "synckit": "0.8.8" - }, - "browser": { - "./internal/shims/getBuiltinModule.mjs": "./internal/shims/nullGetBuiltinModule.mjs", - "./internal/shims/getBuiltinModule.js": "./internal/shims/nullGetBuiltinModule.js" - }, "imports": { "@gitpod/sdk": ".", "@gitpod/sdk/*": "./src/*" diff --git a/src/client.ts b/src/client.ts index d7e3523..f6fcad0 100644 --- a/src/client.ts +++ b/src/client.ts @@ -27,6 +27,8 @@ import { EnvironmentClassesPageResponse, type EnvironmentsPageParams, EnvironmentsPageResponse, + type GatewaysPageParams, + GatewaysPageResponse, type GroupsPageParams, GroupsPageResponse, type IntegrationsPageParams, @@ -41,6 +43,8 @@ import { PoliciesPageResponse, type ProjectsPageParams, ProjectsPageResponse, + type RecordsPageParams, + RecordsPageResponse, type RunnersPageParams, RunnersPageResponse, type SSOConfigurationsPageParams, @@ -49,8 +53,6 @@ import { SecretsPageResponse, type ServicesPageParams, ServicesPageResponse, - type SessionsPageParams, - SessionsPageResponse, type TaskExecutionsPageParams, TaskExecutionsPageResponse, type TasksPageParams, @@ -70,6 +72,8 @@ import { AccountDeleteResponse, AccountGetSSOLoginURLParams, AccountGetSSOLoginURLResponse, + AccountListJoinableOrganizationsParams, + AccountListJoinableOrganizationsResponse, AccountListLoginProvidersParams, AccountMembership, AccountRetrieveParams, @@ -99,6 +103,7 @@ import { ResourceOperation, ResourceType, } from './resources/events'; +import { GatewayListParams, Gateways } from './resources/gateways'; import { Group, GroupListParams, Groups, GroupsGroupsPage } from './resources/groups'; import { IDTokenVersion, @@ -126,10 +131,10 @@ import { SecretsSecretsPage, } from './resources/secrets'; import { - EnvironmentSession, - EnvironmentSessionsSessionsPage, + EnvironmentUsageRecord, + EnvironmentUsageRecordsRecordsPage, Usage, - UsageListEnvironmentSessionsParams, + UsageListEnvironmentRuntimeRecordsParams, } from './resources/usage'; import { readEnv } from './internal/utils/env'; import { formatRequestDetails, loggerFor } from './internal/utils/log'; @@ -161,6 +166,8 @@ import { EnvironmentStatus, EnvironmentStopParams, EnvironmentStopResponse, + EnvironmentUnarchiveParams, + EnvironmentUnarchiveResponse, EnvironmentUpdateParams, EnvironmentUpdateResponse, Environments, @@ -209,6 +216,7 @@ import { ProjectsProjectsPage, } from './resources/projects/projects'; import { + GatewayInfo, LogLevel, MetricsConfiguration, Runner, @@ -387,6 +395,23 @@ export class Gitpod { this.bearerToken = bearerToken; } + /** + * Create a new client instance re-using the same options given to the current client with optional overriding. + */ + withOptions(options: Partial): this { + return new (this.constructor as any as new (props: ClientOptions) => typeof this)({ + ...this._options, + baseURL: this.baseURL, + maxRetries: this.maxRetries, + timeout: this.timeout, + logger: this.logger, + logLevel: this.logLevel, + fetchOptions: this.fetchOptions, + bearerToken: this.bearerToken, + ...options, + }); + } + protected defaultQuery(): Record | undefined { return this._options.defaultQuery; } @@ -919,6 +944,7 @@ export class Gitpod { editors: API.Editors = new API.Editors(this); environments: API.Environments = new API.Environments(this); events: API.Events = new API.Events(this); + gateways: API.Gateways = new API.Gateways(this); groups: API.Groups = new API.Groups(this); identity: API.Identity = new API.Identity(this); organizations: API.Organizations = new API.Organizations(this); @@ -932,6 +958,7 @@ Gitpod.Accounts = Accounts; Gitpod.Editors = Editors; Gitpod.Environments = Environments; Gitpod.Events = Events; +Gitpod.Gateways = Gateways; Gitpod.Groups = Groups; Gitpod.Identity = Identity; Gitpod.Organizations = Organizations; @@ -967,6 +994,9 @@ export declare namespace Gitpod { type EnvironmentsPageResponse as EnvironmentsPageResponse, }; + export import GatewaysPage = Pagination.GatewaysPage; + export { type GatewaysPageParams as GatewaysPageParams, type GatewaysPageResponse as GatewaysPageResponse }; + export import GroupsPage = Pagination.GroupsPage; export { type GroupsPageParams as GroupsPageParams, type GroupsPageResponse as GroupsPageResponse }; @@ -997,6 +1027,9 @@ export declare namespace Gitpod { export import ProjectsPage = Pagination.ProjectsPage; export { type ProjectsPageParams as ProjectsPageParams, type ProjectsPageResponse as ProjectsPageResponse }; + export import RecordsPage = Pagination.RecordsPage; + export { type RecordsPageParams as RecordsPageParams, type RecordsPageResponse as RecordsPageResponse }; + export import RunnersPage = Pagination.RunnersPage; export { type RunnersPageParams as RunnersPageParams, type RunnersPageResponse as RunnersPageResponse }; @@ -1006,9 +1039,6 @@ export declare namespace Gitpod { export import ServicesPage = Pagination.ServicesPage; export { type ServicesPageParams as ServicesPageParams, type ServicesPageResponse as ServicesPageResponse }; - export import SessionsPage = Pagination.SessionsPage; - export { type SessionsPageParams as SessionsPageParams, type SessionsPageResponse as SessionsPageResponse }; - export import SSOConfigurationsPage = Pagination.SSOConfigurationsPage; export { type SSOConfigurationsPageParams as SSOConfigurationsPageParams, @@ -1036,10 +1066,12 @@ export declare namespace Gitpod { type AccountRetrieveResponse as AccountRetrieveResponse, type AccountDeleteResponse as AccountDeleteResponse, type AccountGetSSOLoginURLResponse as AccountGetSSOLoginURLResponse, + type AccountListJoinableOrganizationsResponse as AccountListJoinableOrganizationsResponse, type LoginProvidersLoginProvidersPage as LoginProvidersLoginProvidersPage, type AccountRetrieveParams as AccountRetrieveParams, type AccountDeleteParams as AccountDeleteParams, type AccountGetSSOLoginURLParams as AccountGetSSOLoginURLParams, + type AccountListJoinableOrganizationsParams as AccountListJoinableOrganizationsParams, type AccountListLoginProvidersParams as AccountListLoginProvidersParams, }; @@ -1073,6 +1105,7 @@ export declare namespace Gitpod { type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse, type EnvironmentStartResponse as EnvironmentStartResponse, type EnvironmentStopResponse as EnvironmentStopResponse, + type EnvironmentUnarchiveResponse as EnvironmentUnarchiveResponse, type EnvironmentsEnvironmentsPage as EnvironmentsEnvironmentsPage, type EnvironmentCreateParams as EnvironmentCreateParams, type EnvironmentRetrieveParams as EnvironmentRetrieveParams, @@ -1085,6 +1118,7 @@ export declare namespace Gitpod { type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams, type EnvironmentStartParams as EnvironmentStartParams, type EnvironmentStopParams as EnvironmentStopParams, + type EnvironmentUnarchiveParams as EnvironmentUnarchiveParams, }; export { @@ -1098,6 +1132,8 @@ export declare namespace Gitpod { type EventWatchParams as EventWatchParams, }; + export { Gateways as Gateways, type GatewayListParams as GatewayListParams }; + export { Groups as Groups, type Group as Group, @@ -1162,6 +1198,7 @@ export declare namespace Gitpod { export { Runners as Runners, + type GatewayInfo as GatewayInfo, type LogLevel as LogLevel, type MetricsConfiguration as MetricsConfiguration, type Runner as Runner, @@ -1209,9 +1246,9 @@ export declare namespace Gitpod { export { Usage as Usage, - type EnvironmentSession as EnvironmentSession, - type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage, - type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams, + type EnvironmentUsageRecord as EnvironmentUsageRecord, + type EnvironmentUsageRecordsRecordsPage as EnvironmentUsageRecordsRecordsPage, + type UsageListEnvironmentRuntimeRecordsParams as UsageListEnvironmentRuntimeRecordsParams, }; export { @@ -1227,6 +1264,7 @@ export declare namespace Gitpod { export type EnvironmentClass = API.EnvironmentClass; export type ErrorCode = API.ErrorCode; export type FieldValue = API.FieldValue; + export type Gateway = API.Gateway; export type OrganizationRole = API.OrganizationRole; export type Principal = API.Principal; export type RunsOn = API.RunsOn; diff --git a/src/core/pagination.ts b/src/core/pagination.ts index f72f6ff..1eaa5cb 100644 --- a/src/core/pagination.ts +++ b/src/core/pagination.ts @@ -388,6 +388,61 @@ export class EnvironmentsPage extends AbstractPage implements Enviro } } +export interface GatewaysPageResponse { + gateways: Array; + + pagination: GatewaysPageResponse.Pagination; +} + +export namespace GatewaysPageResponse { + export interface Pagination { + nextToken?: string; + } +} + +export interface GatewaysPageParams { + pageSize?: number; + + token?: string; +} + +export class GatewaysPage extends AbstractPage implements GatewaysPageResponse { + gateways: Array; + + pagination: GatewaysPageResponse.Pagination; + + constructor( + client: Gitpod, + response: Response, + body: GatewaysPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.gateways = body.gateways || []; + this.pagination = body.pagination || {}; + } + + getPaginatedItems(): Item[] { + return this.gateways ?? []; + } + + nextPageRequestOptions(): PageRequestOptions | null { + const cursor = this.pagination?.nextToken; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + token: cursor, + }, + }; + } +} + export interface GroupsPageResponse { groups: Array; @@ -776,43 +831,43 @@ export class ProjectsPage extends AbstractPage implements ProjectsPa } } -export interface RunnersPageResponse { - pagination: RunnersPageResponse.Pagination; +export interface RecordsPageResponse { + pagination: RecordsPageResponse.Pagination; - runners: Array; + records: Array; } -export namespace RunnersPageResponse { +export namespace RecordsPageResponse { export interface Pagination { nextToken?: string; } } -export interface RunnersPageParams { +export interface RecordsPageParams { pageSize?: number; token?: string; } -export class RunnersPage extends AbstractPage implements RunnersPageResponse { - pagination: RunnersPageResponse.Pagination; +export class RecordsPage extends AbstractPage implements RecordsPageResponse { + pagination: RecordsPageResponse.Pagination; - runners: Array; + records: Array; constructor( client: Gitpod, response: Response, - body: RunnersPageResponse, + body: RecordsPageResponse, options: FinalRequestOptions, ) { super(client, response, body, options); this.pagination = body.pagination || {}; - this.runners = body.runners || []; + this.records = body.records || []; } getPaginatedItems(): Item[] { - return this.runners ?? []; + return this.records ?? []; } nextPageRequestOptions(): PageRequestOptions | null { @@ -831,43 +886,43 @@ export class RunnersPage extends AbstractPage implements RunnersPage } } -export interface SecretsPageResponse { - pagination: SecretsPageResponse.Pagination; +export interface RunnersPageResponse { + pagination: RunnersPageResponse.Pagination; - secrets: Array; + runners: Array; } -export namespace SecretsPageResponse { +export namespace RunnersPageResponse { export interface Pagination { nextToken?: string; } } -export interface SecretsPageParams { +export interface RunnersPageParams { pageSize?: number; token?: string; } -export class SecretsPage extends AbstractPage implements SecretsPageResponse { - pagination: SecretsPageResponse.Pagination; +export class RunnersPage extends AbstractPage implements RunnersPageResponse { + pagination: RunnersPageResponse.Pagination; - secrets: Array; + runners: Array; constructor( client: Gitpod, response: Response, - body: SecretsPageResponse, + body: RunnersPageResponse, options: FinalRequestOptions, ) { super(client, response, body, options); this.pagination = body.pagination || {}; - this.secrets = body.secrets || []; + this.runners = body.runners || []; } getPaginatedItems(): Item[] { - return this.secrets ?? []; + return this.runners ?? []; } nextPageRequestOptions(): PageRequestOptions | null { @@ -886,43 +941,43 @@ export class SecretsPage extends AbstractPage implements SecretsPage } } -export interface ServicesPageResponse { - pagination: ServicesPageResponse.Pagination; +export interface SecretsPageResponse { + pagination: SecretsPageResponse.Pagination; - services: Array; + secrets: Array; } -export namespace ServicesPageResponse { +export namespace SecretsPageResponse { export interface Pagination { nextToken?: string; } } -export interface ServicesPageParams { +export interface SecretsPageParams { pageSize?: number; token?: string; } -export class ServicesPage extends AbstractPage implements ServicesPageResponse { - pagination: ServicesPageResponse.Pagination; +export class SecretsPage extends AbstractPage implements SecretsPageResponse { + pagination: SecretsPageResponse.Pagination; - services: Array; + secrets: Array; constructor( client: Gitpod, response: Response, - body: ServicesPageResponse, + body: SecretsPageResponse, options: FinalRequestOptions, ) { super(client, response, body, options); this.pagination = body.pagination || {}; - this.services = body.services || []; + this.secrets = body.secrets || []; } getPaginatedItems(): Item[] { - return this.services ?? []; + return this.secrets ?? []; } nextPageRequestOptions(): PageRequestOptions | null { @@ -941,43 +996,43 @@ export class ServicesPage extends AbstractPage implements ServicesPa } } -export interface SessionsPageResponse { - pagination: SessionsPageResponse.Pagination; +export interface ServicesPageResponse { + pagination: ServicesPageResponse.Pagination; - sessions: Array; + services: Array; } -export namespace SessionsPageResponse { +export namespace ServicesPageResponse { export interface Pagination { nextToken?: string; } } -export interface SessionsPageParams { +export interface ServicesPageParams { pageSize?: number; token?: string; } -export class SessionsPage extends AbstractPage implements SessionsPageResponse { - pagination: SessionsPageResponse.Pagination; +export class ServicesPage extends AbstractPage implements ServicesPageResponse { + pagination: ServicesPageResponse.Pagination; - sessions: Array; + services: Array; constructor( client: Gitpod, response: Response, - body: SessionsPageResponse, + body: ServicesPageResponse, options: FinalRequestOptions, ) { super(client, response, body, options); this.pagination = body.pagination || {}; - this.sessions = body.sessions || []; + this.services = body.services || []; } getPaginatedItems(): Item[] { - return this.sessions ?? []; + return this.services ?? []; } nextPageRequestOptions(): PageRequestOptions | null { diff --git a/src/internal/detect-platform.ts b/src/internal/detect-platform.ts index c5e273b..e82d95c 100644 --- a/src/internal/detect-platform.ts +++ b/src/internal/detect-platform.ts @@ -85,10 +85,10 @@ const getPlatformProperties = (): PlatformProperties => { return { 'X-Stainless-Lang': 'js', 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': normalizePlatform((globalThis as any).process.platform), - 'X-Stainless-Arch': normalizeArch((globalThis as any).process.arch), + 'X-Stainless-OS': normalizePlatform((globalThis as any).process.platform ?? 'unknown'), + 'X-Stainless-Arch': normalizeArch((globalThis as any).process.arch ?? 'unknown'), 'X-Stainless-Runtime': 'node', - 'X-Stainless-Runtime-Version': (globalThis as any).process.version, + 'X-Stainless-Runtime-Version': (globalThis as any).process.version ?? 'unknown', }; } diff --git a/src/internal/headers.ts b/src/internal/headers.ts index 8659dde..5cc03ce 100644 --- a/src/internal/headers.ts +++ b/src/internal/headers.ts @@ -71,8 +71,8 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator { const targetHeaders = new Headers(); const nullHeaders = new Set(); - const seenHeaders = new Set(); for (const headers of newHeaders) { + const seenHeaders = new Set(); for (const [name, value] of iterateHeaders(headers)) { const lowerName = name.toLowerCase(); if (!seenHeaders.has(lowerName)) { diff --git a/src/internal/shims/crypto.ts b/src/internal/shims/crypto.ts deleted file mode 100644 index 905f81c..0000000 --- a/src/internal/shims/crypto.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { getBuiltinModule } from './getBuiltinModule'; - -type Crypto = { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ - getRandomValues(array: T): T; - /** - * Available only in secure contexts. - * - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) - */ - randomUUID?: () => string; -}; -export let getCrypto: () => Crypto | undefined = function lazyGetCrypto() { - if (getCrypto !== lazyGetCrypto) return getCrypto(); - const crypto: Crypto = (globalThis as any).crypto || (getBuiltinModule?.('node:crypto') as any)?.webcrypto; - getCrypto = () => crypto; - return crypto; -}; diff --git a/src/internal/shims/file.ts b/src/internal/shims/file.ts deleted file mode 100644 index d5dc820..0000000 --- a/src/internal/shims/file.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { getBuiltinModule } from './getBuiltinModule'; - -export let getFile = function lazyGetFile(): FileConstructor { - if (getFile !== lazyGetFile) return getFile(); - // We can drop getBuiltinModule once we no longer support Node < 20.0.0 - const File = (globalThis as any).File ?? (getBuiltinModule?.('node:buffer') as any)?.File; - if (!File) throw new Error('`File` is not defined as a global, which is required for file uploads.'); - getFile = () => File; - return File; -}; - -type FileConstructor = - typeof globalThis extends { File: infer fileConstructor } ? fileConstructor : typeof FallbackFile; -export type File = InstanceType; - -// The infer is to make TS show it as a nice union type, -// instead of literally `ConstructorParameters[0]` -type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; -/** - * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. - */ -declare class FallbackFile extends Blob { - constructor(sources: FallbackBlobSource, fileName: string, options?: any); - /** - * The name of the `File`. - */ - readonly name: string; - /** - * The last modified date of the `File`. - */ - readonly lastModified: number; -} diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts deleted file mode 100644 index 64daa2c..0000000 --- a/src/internal/shims/getBuiltinModule.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Load a Node built-in module. ID may or may not be prefixed by `node:` and - * will be normalized. If we used static imports then our bundle size would be bloated by - * injected polyfills, and if we used dynamic require then in addition to bundlers logging warnings, - * our code would not work when bundled to ESM and run in Node 18. - * @param {string} id ID of the built-in to be loaded. - * @returns {object|undefined} exports of the built-in. Undefined if the built-in - * does not exist. - */ -export let getBuiltinModule: null | ((id: string) => object | undefined) = function getBuiltinModuleLazy( - id: string, -): object | undefined { - try { - if (getBuiltinModule !== getBuiltinModuleLazy) return getBuiltinModule!(id); - if ((process as any).getBuiltinModule) { - getBuiltinModule = (process as any).getBuiltinModule; - } else { - /* Fallback implementation for Node 18 */ - function createFallbackGetBuiltinModule(BuiltinModule: any) { - return function getBuiltinModule(id: string): object | undefined { - id = BuiltinModule.normalizeRequirableId(String(id)); - if (!BuiltinModule.canBeRequiredByUsers(id)) { - return; - } - const mod = BuiltinModule.map.get(id); - mod.compileForPublicLoader(); - return mod.exports; - }; - } - const magicKey = Math.random() + ''; - let module: { BuiltinModule: any } | undefined; - let ObjectPrototype: {} = Blob; - for (let next; (next = Reflect.getPrototypeOf(ObjectPrototype)); ObjectPrototype = next); - try { - const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( - (e) => e.description?.includes('clone'), - )!; - Object.defineProperty(ObjectPrototype, magicKey, { - get() { - module = this; - throw null; - }, - configurable: true, - }); - structuredClone( - new (class extends Blob { - [kClone]() { - return { - deserializeInfo: 'internal/bootstrap/realm:' + magicKey, - }; - } - })([]), - ); - } catch {} - delete (ObjectPrototype as any)[magicKey]; - if (module) { - getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); - } else { - getBuiltinModule = () => undefined; - } - } - return getBuiltinModule!(id); - } catch { - return undefined; - } -}; diff --git a/src/internal/shims/nullGetBuiltinModule.ts b/src/internal/shims/nullGetBuiltinModule.ts deleted file mode 100644 index 8bd2280..0000000 --- a/src/internal/shims/nullGetBuiltinModule.ts +++ /dev/null @@ -1 +0,0 @@ -export const getBuiltinModule = null; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index e92ac69..245e849 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -1,6 +1,6 @@ -import { type File, getFile } from './shims/file'; import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; import type { FilePropertyBag } from './builtin-types'; +import { checkFileSupport } from './uploads'; type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; @@ -85,12 +85,14 @@ export async function toFile( name?: string | null | undefined, options?: FilePropertyBag | undefined, ): Promise { + checkFileSupport(); + // If it's a promise, resolve it. value = await value; // If we've been given a `File` we don't need to do anything if (isFileLike(value)) { - if (value instanceof getFile()) { + if (value instanceof File) { return value; } return makeFile([await value.arrayBuffer()], value.name); diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index fa0627a..ef497d7 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,7 +1,6 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; import type { Gitpod } from '../client'; -import { type File, getFile } from './shims/file'; import { ReadableStreamFrom } from './shims'; export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; @@ -12,6 +11,20 @@ interface BunFile extends Blob { readonly name?: string | undefined; } +export const checkFileSupport = () => { + if (typeof File === 'undefined') { + const { process } = globalThis as any; + const isOldNode = + typeof process?.versions?.node === 'string' && parseInt(process.versions.node.split('.')) < 20; + throw new Error( + '`File` is not defined as a global, which is required for file uploads.' + + (isOldNode ? + " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." + : ''), + ); + } +}; + /** * Typically, this is a native "File" class. * @@ -32,7 +45,7 @@ export function makeFile( fileName: string | undefined, options?: FilePropertyBag, ): File { - const File = getFile(); + checkFileSupport(); return new File(fileBits as any, fileName ?? 'unknown_file', options); } @@ -125,8 +138,7 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. -const isNamedBlob = (value: object) => - value instanceof getFile() || (value instanceof Blob && 'name' in value); +const isNamedBlob = (value: object) => value instanceof Blob && 'name' in value; const isUploadable = (value: unknown) => typeof value === 'object' && diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 5a262c6..b0e53aa 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,12 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { getCrypto } from '../shims/crypto'; - /** * https://stackoverflow.com/a/2117523 */ export let uuid4 = function () { - const crypto = getCrypto(); + const { crypto } = globalThis as any; if (crypto?.randomUUID) { uuid4 = crypto.randomUUID.bind(crypto); return crypto.randomUUID(); diff --git a/src/resources/accounts.ts b/src/resources/accounts.ts index b341c47..393e7ee 100644 --- a/src/resources/accounts.ts +++ b/src/resources/accounts.ts @@ -26,6 +26,11 @@ export class Accounts extends APIResource { * ```yaml * {} * ``` + * + * @example + * ```ts + * const account = await client.accounts.retrieve(); + * ``` */ retrieve(body: AccountRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.AccountService/GetAccount', { body, ...options }); @@ -51,6 +56,13 @@ export class Accounts extends APIResource { * ```yaml * accountId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * ``` + * + * @example + * ```ts + * const account = await client.accounts.delete({ + * accountId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * }); + * ``` */ delete(body: AccountDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.AccountService/DeleteAccount', { body, ...options }); @@ -83,6 +95,13 @@ export class Accounts extends APIResource { * email: "user@company.com" * returnTo: "https://gitpod.io/workspaces" * ``` + * + * @example + * ```ts + * const response = await client.accounts.getSSOLoginURL({ + * email: 'user@company.com', + * }); + * ``` */ getSSOLoginURL( body: AccountGetSSOLoginURLParams, @@ -91,6 +110,43 @@ export class Accounts extends APIResource { return this._client.post('/gitpod.v1.AccountService/GetSSOLoginURL', { body, ...options }); } + /** + * Lists organizations that the currently authenticated account can join. + * + * Use this method to: + * + * - Discover organizations associated with the account's email domain. + * - Allow users to join existing organizations. + * - Display potential organizations during onboarding. + * + * ### Examples + * + * - List joinable organizations: + * + * Retrieves a list of organizations the account can join. + * + * ```yaml + * {} + * ``` + * + * @example + * ```ts + * const response = + * await client.accounts.listJoinableOrganizations(); + * ``` + */ + listJoinableOrganizations( + params: AccountListJoinableOrganizationsParams, + options?: RequestOptions, + ): APIPromise { + const { token, pageSize, ...body } = params; + return this._client.post('/gitpod.v1.AccountService/ListJoinableOrganizations', { + query: { token, pageSize }, + body, + ...options, + }); + } + /** * Lists available login providers with optional filtering. * @@ -121,6 +177,16 @@ export class Accounts extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const loginProvider of client.accounts.listLoginProviders( + * { pagination: { pageSize: 20 } }, + * )) { + * // ... + * } + * ``` */ listLoginProviders( params: AccountListLoginProvidersParams, @@ -330,6 +396,9 @@ export interface Account { avatarUrl?: string; + /** + * @deprecated joinables is deprecated. Use ListJoinableOrganizations instead. + */ joinables?: Array; memberships?: Array; @@ -420,6 +489,10 @@ export interface AccountGetSSOLoginURLResponse { loginUrl: string; } +export interface AccountListJoinableOrganizationsResponse { + joinableOrganizations?: Array; +} + export interface AccountRetrieveParams { empty?: boolean; } @@ -440,6 +513,23 @@ export interface AccountGetSSOLoginURLParams { returnTo?: string | null; } +export interface AccountListJoinableOrganizationsParams { + /** + * Query param: + */ + token?: string; + + /** + * Query param: + */ + pageSize?: number; + + /** + * Body param: + */ + empty?: boolean; +} + export interface AccountListLoginProvidersParams extends LoginProvidersPageParams { /** * Body param: filter contains the filter options for listing login methods @@ -490,10 +580,12 @@ export declare namespace Accounts { type AccountRetrieveResponse as AccountRetrieveResponse, type AccountDeleteResponse as AccountDeleteResponse, type AccountGetSSOLoginURLResponse as AccountGetSSOLoginURLResponse, + type AccountListJoinableOrganizationsResponse as AccountListJoinableOrganizationsResponse, type LoginProvidersLoginProvidersPage as LoginProvidersLoginProvidersPage, type AccountRetrieveParams as AccountRetrieveParams, type AccountDeleteParams as AccountDeleteParams, type AccountGetSSOLoginURLParams as AccountGetSSOLoginURLParams, + type AccountListJoinableOrganizationsParams as AccountListJoinableOrganizationsParams, type AccountListLoginProvidersParams as AccountListLoginProvidersParams, }; } diff --git a/src/resources/editors.ts b/src/resources/editors.ts index 84853ac..bf322de 100644 --- a/src/resources/editors.ts +++ b/src/resources/editors.ts @@ -23,6 +23,13 @@ export class Editors extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const editor = await client.editors.retrieve({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve(body: EditorRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EditorService/GetEditor', { body, ...options }); @@ -61,6 +68,16 @@ export class Editors extends APIResource { * filter: * allowedByPolicy: true * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const editor of client.editors.list({ + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list(params: EditorListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -93,6 +110,15 @@ export class Editors extends APIResource { * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const response = await client.editors.resolveURL({ + * editorId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ resolveURL(body: EditorResolveURLParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EditorService/ResolveEditorURL', { body, ...options }); diff --git a/src/resources/environments/automations/automations.ts b/src/resources/environments/automations/automations.ts index a369c3c..1f8efc2 100644 --- a/src/resources/environments/automations/automations.ts +++ b/src/resources/environments/automations/automations.ts @@ -82,6 +82,35 @@ export class Automations extends APIResource { * triggeredBy: * - postEnvironmentStart * ``` + * + * @example + * ```ts + * const response = + * await client.environments.automations.upsert({ + * automationsFile: { + * services: { + * 'web-server': { + * commands: { + * ready: 'curl -s http://localhost:3000', + * start: 'npm run dev', + * }, + * description: 'Development web server', + * name: 'Web Server', + * triggeredBy: ['postDevcontainerStart'], + * }, + * }, + * tasks: { + * build: { + * command: 'npm run build', + * description: 'Builds the project artifacts', + * name: 'Build Project', + * triggeredBy: ['postEnvironmentStart'], + * }, + * }, + * }, + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ upsert(body: AutomationUpsertParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/UpsertAutomationsFile', { diff --git a/src/resources/environments/automations/services.ts b/src/resources/environments/automations/services.ts index efd2c80..f86390e 100644 --- a/src/resources/environments/automations/services.ts +++ b/src/resources/environments/automations/services.ts @@ -55,6 +55,26 @@ export class Services extends APIResource { * docker: * image: "redis:7" * ``` + * + * @example + * ```ts + * const service = + * await client.environments.automations.services.create({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * metadata: { + * description: 'Runs the development web server', + * name: 'Web Server', + * reference: 'web-server', + * triggeredBy: [{ postDevcontainerStart: true }], + * }, + * spec: { + * commands: { + * ready: 'curl -s http://localhost:3000', + * start: 'npm run dev', + * }, + * }, + * }); + * ``` */ create(body: ServiceCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/CreateService', { body, ...options }); @@ -79,6 +99,14 @@ export class Services extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const service = + * await client.environments.automations.services.retrieve({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve(body: ServiceRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/GetService', { body, ...options }); @@ -120,6 +148,20 @@ export class Services extends APIResource { * - postDevcontainerStart: true * - manual: true * ``` + * + * @example + * ```ts + * const service = + * await client.environments.automations.services.update({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * spec: { + * commands: { + * ready: 'curl -s http://localhost:8080', + * start: 'npm run start:dev', + * }, + * }, + * }); + * ``` */ update(body: ServiceUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/UpdateService', { body, ...options }); @@ -157,6 +199,19 @@ export class Services extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const service of client.environments.automations.services.list( + * { + * filter: { references: ['web-server', 'database'] }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list(params: ServiceListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -196,6 +251,14 @@ export class Services extends APIResource { * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * force: true * ``` + * + * @example + * ```ts + * const service = + * await client.environments.automations.services.delete({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: ServiceDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/DeleteService', { body, ...options }); @@ -221,6 +284,14 @@ export class Services extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.environments.automations.services.start({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ start(body: ServiceStartParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/StartService', { body, ...options }); @@ -246,6 +317,14 @@ export class Services extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.environments.automations.services.stop({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ stop(body: ServiceStopParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/StopService', { body, ...options }); diff --git a/src/resources/environments/automations/tasks/executions.ts b/src/resources/environments/automations/tasks/executions.ts index 47410d8..1f2483b 100644 --- a/src/resources/environments/automations/tasks/executions.ts +++ b/src/resources/environments/automations/tasks/executions.ts @@ -27,6 +27,14 @@ export class Executions extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const execution = + * await client.environments.automations.tasks.executions.retrieve( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ retrieve(body: ExecutionRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/GetTaskExecution', { @@ -67,6 +75,24 @@ export class Executions extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const taskExecution of client.environments.automations.tasks.executions.list( + * { + * filter: { + * phases: [ + * 'TASK_EXECUTION_PHASE_RUNNING', + * 'TASK_EXECUTION_PHASE_FAILED', + * ], + * }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: ExecutionListParams, @@ -98,6 +124,14 @@ export class Executions extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.environments.automations.tasks.executions.stop( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ stop(body: ExecutionStopParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/StopTaskExecution', { diff --git a/src/resources/environments/automations/tasks/tasks.ts b/src/resources/environments/automations/tasks/tasks.ts index 6a85c1f..6543b3d 100644 --- a/src/resources/environments/automations/tasks/tasks.ts +++ b/src/resources/environments/automations/tasks/tasks.ts @@ -61,6 +61,21 @@ export class Tasks extends APIResource { * command: "npm test" * dependsOn: ["d2c94c27-3b76-4a42-b88c-95a85e392c68"] * ``` + * + * @example + * ```ts + * const task = + * await client.environments.automations.tasks.create({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * metadata: { + * description: 'Builds the project artifacts', + * name: 'Build Project', + * reference: 'build', + * triggeredBy: [{ postEnvironmentStart: true }], + * }, + * spec: { command: 'npm run build' }, + * }); + * ``` */ create(body: TaskCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/CreateTask', { body, ...options }); @@ -84,6 +99,14 @@ export class Tasks extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const task = + * await client.environments.automations.tasks.retrieve({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve(body: TaskRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/GetTask', { body, ...options }); @@ -122,6 +145,15 @@ export class Tasks extends APIResource { * trigger: * - postEnvironmentStart: true * ``` + * + * @example + * ```ts + * const task = + * await client.environments.automations.tasks.update({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * spec: { command: 'npm run test:coverage' }, + * }); + * ``` */ update(body: TaskUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/UpdateTask', { body, ...options }); @@ -159,6 +191,19 @@ export class Tasks extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const task of client.environments.automations.tasks.list( + * { + * filter: { references: ['build', 'test'] }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list(params: TaskListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -187,6 +232,14 @@ export class Tasks extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const task = + * await client.environments.automations.tasks.delete({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: TaskDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/DeleteTask', { body, ...options }); @@ -211,6 +264,14 @@ export class Tasks extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.environments.automations.tasks.start({ + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ start(body: TaskStartParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentAutomationService/StartTask', { body, ...options }); diff --git a/src/resources/environments/classes.ts b/src/resources/environments/classes.ts index 709e8bc..fa0223f 100644 --- a/src/resources/environments/classes.ts +++ b/src/resources/environments/classes.ts @@ -31,6 +31,14 @@ export class Classes extends APIResource { * ``` * * buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const environmentClass of client.environments.classes.list()) { + * // ... + * } + * ``` */ list( params: ClassListParams, diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts index 695ee9e..229ccb8 100644 --- a/src/resources/environments/environments.ts +++ b/src/resources/environments/environments.ts @@ -84,6 +84,28 @@ export class Environments extends APIResource { * admission: "ADMISSION_LEVEL_EVERYONE" * name: "Web App" * ``` + * + * @example + * ```ts + * const environment = await client.environments.create({ + * spec: { + * content: { + * initializer: { + * specs: [ + * { + * contextUrl: { + * url: 'https://github.com/gitpod-io/gitpod', + * }, + * }, + * ], + * }, + * }, + * machine: { + * class: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * }, + * }); + * ``` */ create(body: EnvironmentCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/CreateEnvironment', { body, ...options }); @@ -110,6 +132,13 @@ export class Environments extends APIResource { * ```yaml * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const environment = await client.environments.retrieve({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ retrieve( body: EnvironmentRetrieveParams, @@ -169,6 +198,21 @@ export class Environments extends APIResource { * * Note: Machine class changes require stopping the environment and creating a new * one. + * + * @example + * ```ts + * const environment = await client.environments.update({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * spec: { + * sshPublicKeys: [ + * { + * id: '0194b7c1-c954-718d-91a4-9a742aa5fc11', + * value: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...', + * }, + * ], + * }, + * }); + * ``` */ update(body: EnvironmentUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/UpdateEnvironment', { body, ...options }); @@ -212,6 +256,21 @@ export class Environments extends APIResource { * filter: * statusPhases: ["ENVIRONMENT_PHASE_STOPPED", "ENVIRONMENT_PHASE_DELETED"] * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const environment of client.environments.list({ + * filter: { + * creatorIds: ['f53d2330-3795-4c5d-a1f3-453121af9c60'], + * runnerIds: [ + * 'e6aa9c54-89d3-42c1-ac31-bd8d8f1concentrate', + * ], + * }, + * })) { + * // ... + * } + * ``` */ list( params: EnvironmentListParams, @@ -250,6 +309,13 @@ export class Environments extends APIResource { * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * force: true * ``` + * + * @example + * ```ts + * const environment = await client.environments.delete({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ delete(body: EnvironmentDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/DeleteEnvironment', { body, ...options }); @@ -270,6 +336,14 @@ export class Environments extends APIResource { * ```yaml * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const response = + * await client.environments.createEnvironmentToken({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ createEnvironmentToken( body: EnvironmentCreateEnvironmentTokenParams, @@ -312,6 +386,20 @@ export class Environments extends APIResource { * timeout: * disconnected: "14400s" # 4 hours in seconds * ``` + * + * @example + * ```ts + * const response = + * await client.environments.createFromProject({ + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * spec: { + * machine: { + * class: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * timeout: { disconnected: '14400s' }, + * }, + * }); + * ``` */ createFromProject( body: EnvironmentCreateFromProjectParams, @@ -338,6 +426,13 @@ export class Environments extends APIResource { * ```yaml * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const response = await client.environments.createLogsToken({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ createLogsToken( body: EnvironmentCreateLogsTokenParams, @@ -367,6 +462,17 @@ export class Environments extends APIResource { * source: "VS Code" * timestamp: "2025-02-12T14:30:00Z" * ``` + * + * @example + * ```ts + * const response = await client.environments.markActive({ + * activitySignal: { + * source: 'VS Code', + * timestamp: '2025-02-12T14:30:00Z', + * }, + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ markActive(body: EnvironmentMarkActiveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/MarkEnvironmentActive', { body, ...options }); @@ -388,6 +494,13 @@ export class Environments extends APIResource { * ```yaml * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const response = await client.environments.start({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ start(body: EnvironmentStartParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/StartEnvironment', { body, ...options }); @@ -408,10 +521,39 @@ export class Environments extends APIResource { * ```yaml * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const response = await client.environments.stop({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` */ stop(body: EnvironmentStopParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.EnvironmentService/StopEnvironment', { body, ...options }); } + + /** + * Unarchives an environment. + * + * ### Examples + * + * - Unarchive an environment: + * + * ```yaml + * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" + * ``` + * + * @example + * ```ts + * const response = await client.environments.unarchive({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * }); + * ``` + */ + unarchive(body: EnvironmentUnarchiveParams, options?: RequestOptions): APIPromise { + return this._client.post('/gitpod.v1.EnvironmentService/UnarchiveEnvironment', { body, ...options }); + } } export type EnvironmentsEnvironmentsPage = EnvironmentsPage; @@ -481,6 +623,12 @@ export interface EnvironmentMetadata { */ annotations?: Record; + /** + * Time when the Environment was archived. If not set, the environment is not + * archived. + */ + archivedAt?: string; + /** * Time when the Environment was created. */ @@ -1301,6 +1449,8 @@ export type EnvironmentStartResponse = unknown; export type EnvironmentStopResponse = unknown; +export type EnvironmentUnarchiveResponse = unknown; + export interface EnvironmentCreateParams { /** * spec is the configuration of the environment that's required for the to start @@ -1472,6 +1622,16 @@ export interface EnvironmentListParams extends EnvironmentsPageParams { export namespace EnvironmentListParams { export interface Filter { + /** + * archival_status filters the response based on environment archive status + */ + archivalStatus?: + | 'ARCHIVAL_STATUS_UNSPECIFIED' + | 'ARCHIVAL_STATUS_ACTIVE' + | 'ARCHIVAL_STATUS_ARCHIVED' + | 'ARCHIVAL_STATUS_ALL' + | null; + /** * creator_ids filters the response to only Environments created by specified * members @@ -1594,6 +1754,15 @@ export interface EnvironmentStopParams { environmentId?: string; } +export interface EnvironmentUnarchiveParams { + /** + * environment_id specifies the environment to unarchive. + * + * +required + */ + environmentId?: string; +} + Environments.Automations = Automations; Environments.Classes = Classes; @@ -1616,6 +1785,7 @@ export declare namespace Environments { type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse, type EnvironmentStartResponse as EnvironmentStartResponse, type EnvironmentStopResponse as EnvironmentStopResponse, + type EnvironmentUnarchiveResponse as EnvironmentUnarchiveResponse, type EnvironmentsEnvironmentsPage as EnvironmentsEnvironmentsPage, type EnvironmentCreateParams as EnvironmentCreateParams, type EnvironmentRetrieveParams as EnvironmentRetrieveParams, @@ -1628,6 +1798,7 @@ export declare namespace Environments { type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams, type EnvironmentStartParams as EnvironmentStartParams, type EnvironmentStopParams as EnvironmentStopParams, + type EnvironmentUnarchiveParams as EnvironmentUnarchiveParams, }; export { diff --git a/src/resources/environments/index.ts b/src/resources/environments/index.ts index 4378540..f106742 100644 --- a/src/resources/environments/index.ts +++ b/src/resources/environments/index.ts @@ -26,6 +26,7 @@ export { type EnvironmentMarkActiveResponse, type EnvironmentStartResponse, type EnvironmentStopResponse, + type EnvironmentUnarchiveResponse, type EnvironmentCreateParams, type EnvironmentRetrieveParams, type EnvironmentUpdateParams, @@ -37,5 +38,6 @@ export { type EnvironmentMarkActiveParams, type EnvironmentStartParams, type EnvironmentStopParams, + type EnvironmentUnarchiveParams, type EnvironmentsEnvironmentsPage, } from './environments'; diff --git a/src/resources/events.ts b/src/resources/events.ts index 109d1aa..1cdccaf 100644 --- a/src/resources/events.ts +++ b/src/resources/events.ts @@ -37,6 +37,20 @@ export class Events extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const eventListResponse of client.events.list({ + * filter: { + * actorIds: ['d2c94c27-3b76-4a42-b88c-95a85e392c68'], + * actorPrincipals: ['PRINCIPAL_USER'], + * }, + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list( params: EventListParams, @@ -69,6 +83,11 @@ export class Events extends APIResource { * - Environment scope: Watch events for a specific environment, including its * tasks, task executions, and services. Use by setting environment_id to the * UUID of the environment to watch. + * + * @example + * ```ts + * const response = await client.events.watch(); + * ``` */ watch(body: EventWatchParams, options?: RequestOptions): APIPromise> { return this._client diff --git a/src/resources/gateways.ts b/src/resources/gateways.ts new file mode 100644 index 0000000..4edba87 --- /dev/null +++ b/src/resources/gateways.ts @@ -0,0 +1,57 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../core/resource'; +import * as Shared from './shared'; +import { GatewaysGatewaysPage } from './shared'; +import { GatewaysPage, type GatewaysPageParams, PagePromise } from '../core/pagination'; +import { RequestOptions } from '../internal/request-options'; + +export class Gateways extends APIResource { + /** + * ListGateways + */ + list( + params: GatewayListParams, + options?: RequestOptions, + ): PagePromise { + const { token, pageSize, ...body } = params; + return this._client.getAPIList('/gitpod.v1.GatewayService/ListGateways', GatewaysPage, { + query: { token, pageSize }, + body, + method: 'post', + ...options, + }); + } +} + +export interface GatewayListParams extends GatewaysPageParams { + /** + * Body param: pagination contains the pagination options for listing gateways + */ + pagination?: GatewayListParams.Pagination; +} + +export namespace GatewayListParams { + /** + * pagination contains the pagination options for listing gateways + */ + export interface Pagination { + /** + * Token for the next set of results that was returned as next_token of a + * PaginationResponse + */ + token?: string; + + /** + * Page size is the maximum number of results to retrieve per page. Defaults to 25. + * Maximum 100. + */ + pageSize?: number; + } +} + +export declare namespace Gateways { + export { type GatewayListParams as GatewayListParams }; +} + +export { type GatewaysGatewaysPage }; diff --git a/src/resources/groups.ts b/src/resources/groups.ts index 56384a4..2ba760c 100644 --- a/src/resources/groups.ts +++ b/src/resources/groups.ts @@ -35,6 +35,16 @@ export class Groups extends APIResource { * pageSize: 50 * token: "next-page-token-from-previous-response" * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const group of client.groups.list({ + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list(params: GroupListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; diff --git a/src/resources/identity.ts b/src/resources/identity.ts index d1fa01f..3b2dc4b 100644 --- a/src/resources/identity.ts +++ b/src/resources/identity.ts @@ -24,6 +24,13 @@ export class Identity extends APIResource { * ```yaml * exchangeToken: "exchange-token-value" * ``` + * + * @example + * ```ts + * const response = await client.identity.exchangeToken({ + * exchangeToken: 'exchange-token-value', + * }); + * ``` */ exchangeToken( body: IdentityExchangeTokenParams, @@ -51,6 +58,12 @@ export class Identity extends APIResource { * ```yaml * {} * ``` + * + * @example + * ```ts + * const response = + * await client.identity.getAuthenticatedIdentity(); + * ``` */ getAuthenticatedIdentity( body: IdentityGetAuthenticatedIdentityParams, @@ -88,6 +101,16 @@ export class Identity extends APIResource { * - "https://api.gitpod.io" * - "https://ws.gitpod.io" * ``` + * + * @example + * ```ts + * const response = await client.identity.getIDToken({ + * audience: [ + * 'https://api.gitpod.io', + * 'https://ws.gitpod.io', + * ], + * }); + * ``` */ getIDToken( body: IdentityGetIDTokenParams, diff --git a/src/resources/index.ts b/src/resources/index.ts index 664e230..6fdf73f 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -10,9 +10,11 @@ export { type AccountRetrieveResponse, type AccountDeleteResponse, type AccountGetSSOLoginURLResponse, + type AccountListJoinableOrganizationsResponse, type AccountRetrieveParams, type AccountDeleteParams, type AccountGetSSOLoginURLParams, + type AccountListJoinableOrganizationsParams, type AccountListLoginProvidersParams, type LoginProvidersLoginProvidersPage, } from './accounts'; @@ -45,6 +47,7 @@ export { type EnvironmentMarkActiveResponse, type EnvironmentStartResponse, type EnvironmentStopResponse, + type EnvironmentUnarchiveResponse, type EnvironmentCreateParams, type EnvironmentRetrieveParams, type EnvironmentUpdateParams, @@ -56,6 +59,7 @@ export { type EnvironmentMarkActiveParams, type EnvironmentStartParams, type EnvironmentStopParams, + type EnvironmentUnarchiveParams, type EnvironmentsEnvironmentsPage, } from './environments/environments'; export { @@ -68,6 +72,7 @@ export { type EventWatchParams, type EventListResponsesEntriesPage, } from './events'; +export { Gateways, type GatewayListParams } from './gateways'; export { Groups, type Group, type GroupListParams, type GroupsGroupsPage } from './groups'; export { Identity, @@ -123,6 +128,7 @@ export { } from './projects/projects'; export { Runners, + type GatewayInfo, type LogLevel, type MetricsConfiguration, type Runner, @@ -168,9 +174,9 @@ export { } from './secrets'; export { Usage, - type EnvironmentSession, - type UsageListEnvironmentSessionsParams, - type EnvironmentSessionsSessionsPage, + type EnvironmentUsageRecord, + type UsageListEnvironmentRuntimeRecordsParams, + type EnvironmentUsageRecordsRecordsPage, } from './usage'; export { Users, diff --git a/src/resources/organizations/domain-verifications.ts b/src/resources/organizations/domain-verifications.ts index 51e3a9e..911c257 100644 --- a/src/resources/organizations/domain-verifications.ts +++ b/src/resources/organizations/domain-verifications.ts @@ -39,6 +39,15 @@ export class DomainVerifications extends APIResource { * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * domain: "acme-subsidiary.com" * ``` + * + * @example + * ```ts + * const domainVerification = + * await client.organizations.domainVerifications.create({ + * domain: 'acme-corp.com', + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ create( body: DomainVerificationCreateParams, @@ -65,6 +74,15 @@ export class DomainVerifications extends APIResource { * ```yaml * domainVerificationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const domainVerification = + * await client.organizations.domainVerifications.retrieve({ + * domainVerificationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve( body: DomainVerificationRetrieveParams, @@ -105,6 +123,19 @@ export class DomainVerifications extends APIResource { * pageSize: 20 * token: "next-page-token-from-previous-response" * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const domainVerification of client.organizations.domainVerifications.list( + * { + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: DomainVerificationListParams, @@ -136,6 +167,15 @@ export class DomainVerifications extends APIResource { * ```yaml * domainVerificationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const domainVerification = + * await client.organizations.domainVerifications.delete({ + * domainVerificationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: DomainVerificationDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/DeleteDomainVerification', { body, ...options }); @@ -159,6 +199,15 @@ export class DomainVerifications extends APIResource { * ```yaml * domainVerificationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.organizations.domainVerifications.verify({ + * domainVerificationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ verify( body: DomainVerificationVerifyParams, diff --git a/src/resources/organizations/invites.ts b/src/resources/organizations/invites.ts index 5dded81..ad18317 100644 --- a/src/resources/organizations/invites.ts +++ b/src/resources/organizations/invites.ts @@ -24,6 +24,13 @@ export class Invites extends APIResource { * ```yaml * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const invite = await client.organizations.invites.create({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ create(body: InviteCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/CreateOrganizationInvite', { body, ...options }); @@ -31,6 +38,13 @@ export class Invites extends APIResource { /** * GetOrganizationInvite + * + * @example + * ```ts + * const invite = await client.organizations.invites.retrieve({ + * organizationId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', + * }); + * ``` */ retrieve(body: InviteRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/GetOrganizationInvite', { body, ...options }); @@ -55,6 +69,14 @@ export class Invites extends APIResource { * ```yaml * inviteId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = + * await client.organizations.invites.getSummary({ + * inviteId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ getSummary(body: InviteGetSummaryParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/GetOrganizationInviteSummary', { diff --git a/src/resources/organizations/organizations.ts b/src/resources/organizations/organizations.ts index 2393f17..6f06f14 100644 --- a/src/resources/organizations/organizations.ts +++ b/src/resources/organizations/organizations.ts @@ -98,6 +98,14 @@ export class Organizations extends APIResource { * joinOrganization: true * inviteAccountsWithMatchingDomain: true * ``` + * + * @example + * ```ts + * const organization = await client.organizations.create({ + * name: 'Acme Corp Engineering', + * joinOrganization: true, + * }); + * ``` */ create(body: OrganizationCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/CreateOrganization', { body, ...options }); @@ -121,6 +129,13 @@ export class Organizations extends APIResource { * ```yaml * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const organization = await client.organizations.retrieve({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ retrieve( body: OrganizationRetrieveParams, @@ -164,6 +179,14 @@ export class Organizations extends APIResource { * inviteDomains: * domains: [] * ``` + * + * @example + * ```ts + * const organization = await client.organizations.update({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * inviteDomains: { domains: [] }, + * }); + * ``` */ update(body: OrganizationUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganization', { body, ...options }); @@ -187,6 +210,13 @@ export class Organizations extends APIResource { * ```yaml * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const organization = await client.organizations.delete({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ delete(body: OrganizationDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/DeleteOrganization', { body, ...options }); @@ -219,6 +249,13 @@ export class Organizations extends APIResource { * ```yaml * inviteId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = await client.organizations.join({ + * inviteId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ join(body: OrganizationJoinParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/JoinOrganization', { body, ...options }); @@ -245,6 +282,13 @@ export class Organizations extends APIResource { * ``` * * Note: Ensure all projects and resources are transferred before leaving. + * + * @example + * ```ts + * const response = await client.organizations.leave({ + * userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * }); + * ``` */ leave(body: OrganizationLeaveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/LeaveOrganization', { body, ...options }); @@ -281,6 +325,19 @@ export class Organizations extends APIResource { * pageSize: 50 * token: "next-page-token-from-previous-response" * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const organizationMember of client.organizations.listMembers( + * { + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ listMembers( params: OrganizationListMembersParams, @@ -325,6 +382,15 @@ export class Organizations extends APIResource { * userId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * role: ORGANIZATION_ROLE_MEMBER * ``` + * + * @example + * ```ts + * const response = await client.organizations.setRole({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * role: 'ORGANIZATION_ROLE_MEMBER', + * }); + * ``` */ setRole(body: OrganizationSetRoleParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/SetRole', { body, ...options }); diff --git a/src/resources/organizations/policies.ts b/src/resources/organizations/policies.ts index 468ef07..c74050a 100644 --- a/src/resources/organizations/policies.ts +++ b/src/resources/organizations/policies.ts @@ -23,6 +23,15 @@ export class Policies extends APIResource { * ```yaml * organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const policy = await client.organizations.policies.retrieve( + * { + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }, + * ); + * ``` */ retrieve(body: PolicyRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/GetOrganizationPolicies', { body, ...options }); @@ -62,6 +71,16 @@ export class Policies extends APIResource { * maximumRunningEnvironmentsPerUser: "5" * maximumEnvironmentsPerUser: "20" * ``` + * + * @example + * ```ts + * const policy = await client.organizations.policies.update({ + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * maximumEnvironmentsPerUser: '20', + * maximumEnvironmentTimeout: '3600s', + * maximumRunningEnvironmentsPerUser: '5', + * }); + * ``` */ update(body: PolicyUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganizationPolicies', { @@ -124,6 +143,12 @@ export interface OrganizationPolicies { */ organizationId: string; + /** + * port_sharing_disabled controls whether port sharing is disabled in the + * organization + */ + portSharingDisabled: boolean; + /** * maximum_environment_timeout controls the maximum timeout allowed for * environments in seconds. 0 means no limit (never). Minimum duration is 30 @@ -204,6 +229,12 @@ export interface PolicyUpdateParams { * projects by non-admin users */ membersRequireProjects?: boolean | null; + + /** + * port_sharing_disabled controls whether port sharing is disabled in the + * organization + */ + portSharingDisabled?: boolean | null; } export declare namespace Policies { diff --git a/src/resources/organizations/sso-configurations.ts b/src/resources/organizations/sso-configurations.ts index a447375..5bc4655 100644 --- a/src/resources/organizations/sso-configurations.ts +++ b/src/resources/organizations/sso-configurations.ts @@ -41,6 +41,19 @@ export class SSOConfigurations extends APIResource { * issuerUrl: "https://sso.acme-corp.com" * emailDomain: "acme-corp.com" * ``` + * + * @example + * ```ts + * const ssoConfiguration = + * await client.organizations.ssoConfigurations.create({ + * clientId: + * '012345678-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com', + * clientSecret: 'GOCSPX-abcdefghijklmnopqrstuvwxyz123456', + * emailDomain: 'acme-corp.com', + * issuerUrl: 'https://accounts.google.com', + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ create( body: SSOConfigurationCreateParams, @@ -67,6 +80,15 @@ export class SSOConfigurations extends APIResource { * ```yaml * ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const ssoConfiguration = + * await client.organizations.ssoConfigurations.retrieve({ + * ssoConfigurationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve( body: SSOConfigurationRetrieveParams, @@ -106,6 +128,17 @@ export class SSOConfigurations extends APIResource { * ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * state: SSO_CONFIGURATION_STATE_ACTIVE * ``` + * + * @example + * ```ts + * const ssoConfiguration = + * await client.organizations.ssoConfigurations.update({ + * ssoConfigurationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * clientId: 'new-client-id', + * clientSecret: 'new-client-secret', + * }); + * ``` */ update(body: SSOConfigurationUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/UpdateSSOConfiguration', { body, ...options }); @@ -143,6 +176,19 @@ export class SSOConfigurations extends APIResource { * pageSize: 20 * token: "next-page-token-from-previous-response" * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const ssoConfiguration of client.organizations.ssoConfigurations.list( + * { + * organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: SSOConfigurationListParams, @@ -174,6 +220,15 @@ export class SSOConfigurations extends APIResource { * ```yaml * ssoConfigurationId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const ssoConfiguration = + * await client.organizations.ssoConfigurations.delete({ + * ssoConfigurationId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: SSOConfigurationDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.OrganizationService/DeleteSSOConfiguration', { body, ...options }); diff --git a/src/resources/projects/policies.ts b/src/resources/projects/policies.ts index ea39ec5..3676967 100644 --- a/src/resources/projects/policies.ts +++ b/src/resources/projects/policies.ts @@ -26,6 +26,15 @@ export class Policies extends APIResource { * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * role: PROJECT_ROLE_ADMIN * ``` + * + * @example + * ```ts + * const policy = await client.projects.policies.create({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * role: 'PROJECT_ROLE_ADMIN', + * }); + * ``` */ create(body: PolicyCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/CreateProjectPolicy', { body, ...options }); @@ -51,6 +60,15 @@ export class Policies extends APIResource { * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * role: PROJECT_ROLE_EDITOR * ``` + * + * @example + * ```ts + * const policy = await client.projects.policies.update({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * role: 'PROJECT_ROLE_EDITOR', + * }); + * ``` */ update(body: PolicyUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/UpdateProjectPolicy', { body, ...options }); @@ -76,6 +94,19 @@ export class Policies extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const projectPolicy of client.projects.policies.list( + * { + * pagination: { pageSize: 20 }, + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }, + * )) { + * // ... + * } + * ``` */ list( params: PolicyListParams, @@ -108,6 +139,14 @@ export class Policies extends APIResource { * projectId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * ``` + * + * @example + * ```ts + * const policy = await client.projects.policies.delete({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ delete(body: PolicyDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/DeleteProjectPolicy', { body, ...options }); diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts index 27f10b3..25e1df1 100644 --- a/src/resources/projects/projects.ts +++ b/src/resources/projects/projects.ts @@ -64,6 +64,22 @@ export class Projects extends APIResource { * devcontainerFilePath: ".devcontainer/devcontainer.json" * automationsFilePath: ".gitpod/automations.yaml" * ``` + * + * @example + * ```ts + * const project = await client.projects.create({ + * environmentClass: { + * environmentClassId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * initializer: { + * specs: [ + * { git: { remoteUri: 'https://github.com/org/repo' } }, + * ], + * }, + * name: 'Web Application', + * }); + * ``` */ create(body: ProjectCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/CreateProject', { body, ...options }); @@ -87,6 +103,13 @@ export class Projects extends APIResource { * ```yaml * projectId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const project = await client.projects.retrieve({ + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ retrieve(body: ProjectRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/GetProject', { body, ...options }); @@ -122,6 +145,17 @@ export class Projects extends APIResource { * environmentClass: * environmentClassId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const project = await client.projects.update({ + * environmentClass: { + * environmentClassId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ update(body: ProjectUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/UpdateProject', { body, ...options }); @@ -146,6 +180,16 @@ export class Projects extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const project of client.projects.list({ + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list(params: ProjectListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -175,6 +219,13 @@ export class Projects extends APIResource { * ```yaml * projectId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" * ``` + * + * @example + * ```ts + * const project = await client.projects.delete({ + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }); + * ``` */ delete(body: ProjectDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.ProjectService/DeleteProject', { body, ...options }); @@ -199,6 +250,15 @@ export class Projects extends APIResource { * name: "Frontend Project" * environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048" * ``` + * + * @example + * ```ts + * const response = + * await client.projects.createFromEnvironment({ + * environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048', + * name: 'Frontend Project', + * }); + * ``` */ createFromEnvironment( body: ProjectCreateFromEnvironmentParams, diff --git a/src/resources/runners/configurations/configurations.ts b/src/resources/runners/configurations/configurations.ts index db30ece..e77550d 100644 --- a/src/resources/runners/configurations/configurations.ts +++ b/src/resources/runners/configurations/configurations.ts @@ -83,6 +83,21 @@ export class Configurations extends APIResource { * oauthClientId: "client_id" * oauthPlaintextClientSecret: "client_secret" * ``` + * + * @example + * ```ts + * const response = + * await client.runners.configurations.validate({ + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * scmIntegration: { + * host: 'github.com', + * id: 'integration-id', + * oauthClientId: 'client_id', + * oauthPlaintextClientSecret: 'client_secret', + * scmId: 'github', + * }, + * }); + * ``` */ validate( body: ConfigurationValidateParams, @@ -146,6 +161,12 @@ export namespace ConfigurationValidateParams { host?: string; + /** + * issuer_url can be set to override the authentication provider URL, if it doesn't + * match the SCM host. + */ + issuerUrl?: string | null; + /** * oauth_client_id is the OAuth app's client ID, if OAuth is configured. If * configured, oauth_client_secret must also be set. diff --git a/src/resources/runners/configurations/environment-classes.ts b/src/resources/runners/configurations/environment-classes.ts index 1db7137..113c0eb 100644 --- a/src/resources/runners/configurations/environment-classes.ts +++ b/src/resources/runners/configurations/environment-classes.ts @@ -38,6 +38,22 @@ export class EnvironmentClasses extends APIResource { * - key: "memory" * value: "16384" * ``` + * + * @example + * ```ts + * const environmentClass = + * await client.runners.configurations.environmentClasses.create( + * { + * configuration: [ + * { key: 'cpu', value: '8' }, + * { key: 'memory', value: '16384' }, + * ], + * description: '8 CPU, 16GB RAM', + * displayName: 'Large Instance', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * ); + * ``` */ create( body: EnvironmentClassCreateParams, @@ -67,6 +83,17 @@ export class EnvironmentClasses extends APIResource { * ```yaml * environmentClassId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const environmentClass = + * await client.runners.configurations.environmentClasses.retrieve( + * { + * environmentClassId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * ); + * ``` */ retrieve( body: EnvironmentClassRetrieveParams, @@ -99,6 +126,20 @@ export class EnvironmentClasses extends APIResource { * description: "16 CPU, 32GB RAM" * enabled: true * ``` + * + * @example + * ```ts + * const environmentClass = + * await client.runners.configurations.environmentClasses.update( + * { + * description: '16 CPU, 32GB RAM', + * displayName: 'Updated Large Instance', + * enabled: true, + * environmentClassId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * ); + * ``` */ update(body: EnvironmentClassUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/UpdateEnvironmentClass', { @@ -139,6 +180,19 @@ export class EnvironmentClasses extends APIResource { * ``` * * buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const environmentClass of client.runners.configurations.environmentClasses.list( + * { + * filter: { enabled: true }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: EnvironmentClassListParams, diff --git a/src/resources/runners/configurations/host-authentication-tokens.ts b/src/resources/runners/configurations/host-authentication-tokens.ts index 8196628..5a538a9 100644 --- a/src/resources/runners/configurations/host-authentication-tokens.ts +++ b/src/resources/runners/configurations/host-authentication-tokens.ts @@ -30,6 +30,22 @@ export class HostAuthenticationTokens extends APIResource { * expiresAt: "2024-12-31T23:59:59Z" * refreshToken: "ghr_xxxxxxxxxxxx" * ``` + * + * @example + * ```ts + * const hostAuthenticationToken = + * await client.runners.configurations.hostAuthenticationTokens.create( + * { + * token: 'gho_xxxxxxxxxxxx', + * expiresAt: '2024-12-31T23:59:59Z', + * host: 'github.com', + * refreshToken: 'ghr_xxxxxxxxxxxx', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * source: 'HOST_AUTHENTICATION_TOKEN_SOURCE_OAUTH', + * userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * }, + * ); + * ``` */ create( body: HostAuthenticationTokenCreateParams, @@ -59,6 +75,14 @@ export class HostAuthenticationTokens extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const hostAuthenticationToken = + * await client.runners.configurations.hostAuthenticationTokens.retrieve( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ retrieve( body: HostAuthenticationTokenRetrieveParams, @@ -91,6 +115,19 @@ export class HostAuthenticationTokens extends APIResource { * expiresAt: "2024-12-31T23:59:59Z" * refreshToken: "ghr_xxxxxxxxxxxx" * ``` + * + * @example + * ```ts + * const hostAuthenticationToken = + * await client.runners.configurations.hostAuthenticationTokens.update( + * { + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * token: 'gho_xxxxxxxxxxxx', + * expiresAt: '2024-12-31T23:59:59Z', + * refreshToken: 'ghr_xxxxxxxxxxxx', + * }, + * ); + * ``` */ update(body: HostAuthenticationTokenUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/UpdateHostAuthenticationToken', { @@ -129,6 +166,21 @@ export class HostAuthenticationTokens extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const hostAuthenticationToken of client.runners.configurations.hostAuthenticationTokens.list( + * { + * filter: { + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: HostAuthenticationTokenListParams, @@ -160,6 +212,14 @@ export class HostAuthenticationTokens extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const hostAuthenticationToken = + * await client.runners.configurations.hostAuthenticationTokens.delete( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ delete(body: HostAuthenticationTokenDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/DeleteHostAuthenticationToken', { diff --git a/src/resources/runners/configurations/schema.ts b/src/resources/runners/configurations/schema.ts index cd1222c..fd110fe 100644 --- a/src/resources/runners/configurations/schema.ts +++ b/src/resources/runners/configurations/schema.ts @@ -23,6 +23,14 @@ export class Schema extends APIResource { * ```yaml * runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const schema = + * await client.runners.configurations.schema.retrieve({ + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve(body: SchemaRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/GetRunnerConfigurationSchema', { diff --git a/src/resources/runners/configurations/scm-integrations.ts b/src/resources/runners/configurations/scm-integrations.ts index ebdc52b..b458f97 100644 --- a/src/resources/runners/configurations/scm-integrations.ts +++ b/src/resources/runners/configurations/scm-integrations.ts @@ -28,6 +28,20 @@ export class ScmIntegrations extends APIResource { * oauthClientId: "client_id" * oauthPlaintextClientSecret: "client_secret" * ``` + * + * @example + * ```ts + * const scmIntegration = + * await client.runners.configurations.scmIntegrations.create( + * { + * host: 'github.com', + * oauthClientId: 'client_id', + * oauthPlaintextClientSecret: 'client_secret', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * scmId: 'github', + * }, + * ); + * ``` */ create( body: ScmIntegrationCreateParams, @@ -57,6 +71,14 @@ export class ScmIntegrations extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const scmIntegration = + * await client.runners.configurations.scmIntegrations.retrieve( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ retrieve( body: ScmIntegrationRetrieveParams, @@ -85,6 +107,18 @@ export class ScmIntegrations extends APIResource { * oauthClientId: "new_client_id" * oauthPlaintextClientSecret: "new_client_secret" * ``` + * + * @example + * ```ts + * const scmIntegration = + * await client.runners.configurations.scmIntegrations.update( + * { + * id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * oauthClientId: 'new_client_id', + * oauthPlaintextClientSecret: 'new_client_secret', + * }, + * ); + * ``` */ update(body: ScmIntegrationUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/UpdateSCMIntegration', { @@ -114,6 +148,21 @@ export class ScmIntegrations extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const scmIntegration of client.runners.configurations.scmIntegrations.list( + * { + * filter: { + * runnerIds: ['d2c94c27-3b76-4a42-b88c-95a85e392c68'], + * }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: ScmIntegrationListParams, @@ -145,6 +194,14 @@ export class ScmIntegrations extends APIResource { * ```yaml * id: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const scmIntegration = + * await client.runners.configurations.scmIntegrations.delete( + * { id: 'd2c94c27-3b76-4a42-b88c-95a85e392c68' }, + * ); + * ``` */ delete(body: ScmIntegrationDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerConfigurationService/DeleteSCMIntegration', { @@ -188,6 +245,14 @@ export interface ScmIntegrationOAuthConfig { * public key. */ encryptedClientSecret?: string; + + /** + * issuer_url is used to override the authentication provider URL, if it doesn't + * match the SCM host. + * + * +optional if not set, this account is owned by the installation. + */ + issuerUrl?: string; } export interface ScmIntegrationCreateResponse { @@ -208,6 +273,12 @@ export type ScmIntegrationDeleteResponse = unknown; export interface ScmIntegrationCreateParams { host?: string; + /** + * issuer_url can be set to override the authentication provider URL, if it doesn't + * match the SCM host. + */ + issuerUrl?: string | null; + /** * oauth_client_id is the OAuth app's client ID, if OAuth is configured. If * configured, oauth_plaintext_client_secret must also be set. @@ -238,6 +309,12 @@ export interface ScmIntegrationRetrieveParams { export interface ScmIntegrationUpdateParams { id?: string; + /** + * issuer_url can be set to override the authentication provider URL, if it doesn't + * match the SCM host. + */ + issuerUrl?: string | null; + /** * oauth_client_id can be set to update the OAuth app's client ID. If an empty * string is set, the OAuth configuration will be removed (regardless of whether a diff --git a/src/resources/runners/index.ts b/src/resources/runners/index.ts index 0f5a99a..be65dbf 100644 --- a/src/resources/runners/index.ts +++ b/src/resources/runners/index.ts @@ -23,6 +23,7 @@ export { } from './policies'; export { Runners, + type GatewayInfo, type LogLevel, type MetricsConfiguration, type Runner, diff --git a/src/resources/runners/policies.ts b/src/resources/runners/policies.ts index 0cdd4c1..a49bcf5 100644 --- a/src/resources/runners/policies.ts +++ b/src/resources/runners/policies.ts @@ -26,6 +26,15 @@ export class Policies extends APIResource { * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * role: RUNNER_ROLE_ADMIN * ``` + * + * @example + * ```ts + * const policy = await client.runners.policies.create({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * role: 'RUNNER_ROLE_ADMIN', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ create(body: PolicyCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/CreateRunnerPolicy', { body, ...options }); @@ -51,6 +60,15 @@ export class Policies extends APIResource { * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * role: RUNNER_ROLE_USER * ``` + * + * @example + * ```ts + * const policy = await client.runners.policies.update({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * role: 'RUNNER_ROLE_USER', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ update(body: PolicyUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/UpdateRunnerPolicy', { body, ...options }); @@ -76,6 +94,19 @@ export class Policies extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const runnerPolicy of client.runners.policies.list( + * { + * pagination: { pageSize: 20 }, + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * )) { + * // ... + * } + * ``` */ list( params: PolicyListParams, @@ -108,6 +139,14 @@ export class Policies extends APIResource { * runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * groupId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * ``` + * + * @example + * ```ts + * const policy = await client.runners.policies.delete({ + * groupId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: PolicyDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/DeleteRunnerPolicy', { body, ...options }); diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts index 5abb6dd..e7eaa88 100644 --- a/src/resources/runners/runners.ts +++ b/src/resources/runners/runners.ts @@ -75,6 +75,22 @@ export class Runners extends APIResource { * releaseChannel: RUNNER_RELEASE_CHANNEL_LATEST * autoUpdate: true * ``` + * + * @example + * ```ts + * const runner = await client.runners.create({ + * name: 'Production Runner', + * provider: 'RUNNER_PROVIDER_AWS_EC2', + * spec: { + * configuration: { + * autoUpdate: true, + * region: 'us-west', + * releaseChannel: 'RUNNER_RELEASE_CHANNEL_STABLE', + * }, + * desiredPhase: 'RUNNER_PHASE_ACTIVE', + * }, + * }); + * ``` */ create(body: RunnerCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/CreateRunner', { body, ...options }); @@ -99,6 +115,13 @@ export class Runners extends APIResource { * ```yaml * runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const runner = await client.runners.retrieve({ + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ retrieve(body: RunnerRetrieveParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/GetRunner', { body, ...options }); @@ -128,6 +151,20 @@ export class Runners extends APIResource { * releaseChannel: RUNNER_RELEASE_CHANNEL_LATEST * autoUpdate: true * ``` + * + * @example + * ```ts + * const runner = await client.runners.update({ + * name: 'Updated Runner Name', + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * spec: { + * configuration: { + * autoUpdate: true, + * releaseChannel: 'RUNNER_RELEASE_CHANNEL_LATEST', + * }, + * }, + * }); + * ``` */ update(body: RunnerUpdateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/UpdateRunner', { body, ...options }); @@ -164,6 +201,17 @@ export class Runners extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const runner of client.runners.list({ + * filter: { providers: ['RUNNER_PROVIDER_AWS_EC2'] }, + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list(params: RunnerListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -193,6 +241,13 @@ export class Runners extends APIResource { * ```yaml * runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const runner = await client.runners.delete({ + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: RunnerDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.RunnerService/DeleteRunner', { body, ...options }); @@ -216,6 +271,14 @@ export class Runners extends APIResource { * ```yaml * host: "github.com" * ``` + * + * @example + * ```ts + * const response = + * await client.runners.checkAuthenticationForHost({ + * host: 'github.com', + * }); + * ``` */ checkAuthenticationForHost( body: RunnerCheckAuthenticationForHostParams, @@ -244,6 +307,13 @@ export class Runners extends APIResource { * ```yaml * runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = await client.runners.createRunnerToken({ + * runnerId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ createRunnerToken( body: RunnerCreateRunnerTokenParams, @@ -277,6 +347,13 @@ export class Runners extends APIResource { * ```yaml * contextUrl: "https://github.com/org/repo/tree/main" * ``` + * + * @example + * ```ts + * const response = await client.runners.parseContextURL({ + * contextUrl: 'https://github.com/org/repo/tree/main', + * }); + * ``` */ parseContextURL( body: RunnerParseContextURLParams, @@ -288,6 +365,18 @@ export class Runners extends APIResource { export type RunnersRunnersPage = RunnersPage; +export interface GatewayInfo { + /** + * Gateway represents a system gateway that provides access to services + */ + gateway?: Shared.Gateway; + + /** + * latency is the round-trip time of the runner to the gateway in milliseconds. + */ + latency?: string; +} + export type LogLevel = | 'LOG_LEVEL_UNSPECIFIED' | 'LOG_LEVEL_DEBUG' @@ -435,7 +524,8 @@ export type RunnerProvider = | 'RUNNER_PROVIDER_UNSPECIFIED' | 'RUNNER_PROVIDER_AWS_EC2' | 'RUNNER_PROVIDER_LINUX_HOST' - | 'RUNNER_PROVIDER_DESKTOP_MAC'; + | 'RUNNER_PROVIDER_DESKTOP_MAC' + | 'RUNNER_PROVIDER_MANAGED'; export type RunnerReleaseChannel = | 'RUNNER_RELEASE_CHANNEL_UNSPECIFIED' @@ -469,6 +559,11 @@ export interface RunnerStatus { */ capabilities?: Array; + /** + * gateway_info is information about the gateway to which the runner is connected. + */ + gatewayInfo?: GatewayInfo; + logUrl?: string; /** @@ -490,7 +585,7 @@ export interface RunnerStatus { systemDetails?: string; /** - * Time when the status was last udpated. + * Time when the status was last updated. */ updatedAt?: string; @@ -664,6 +759,12 @@ export interface RunnerCreateParams { */ provider?: RunnerProvider; + /** + * The runner manager id specifies the runner manager for the managed runner. This + * field is mandatory for managed runners, otheriwse should not be set. + */ + runnerManagerId?: string; + spec?: RunnerSpec; } @@ -844,6 +945,7 @@ Runners.Policies = Policies; export declare namespace Runners { export { + type GatewayInfo as GatewayInfo, type LogLevel as LogLevel, type MetricsConfiguration as MetricsConfiguration, type Runner as Runner, diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts index 68c387d..9c812cd 100644 --- a/src/resources/secrets.ts +++ b/src/resources/secrets.ts @@ -52,6 +52,16 @@ export class Secrets extends APIResource { * value: "username:password" * containerRegistryBasicAuthHost: "https://registry.example.com" * ``` + * + * @example + * ```ts + * const secret = await client.secrets.create({ + * environmentVariable: true, + * name: 'DATABASE_URL', + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * value: 'postgresql://user:pass@localhost:5432/db', + * }); + * ``` */ create(body: SecretCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.SecretService/CreateSecret', { body, ...options }); @@ -90,6 +100,21 @@ export class Secrets extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const secret of client.secrets.list({ + * filter: { + * scope: { + * projectId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047', + * }, + * }, + * pagination: { pageSize: 20 }, + * })) { + * // ... + * } + * ``` */ list(params: SecretListParams, options?: RequestOptions): PagePromise { const { token, pageSize, ...body } = params; @@ -118,6 +143,13 @@ export class Secrets extends APIResource { * ```yaml * secretId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const secret = await client.secrets.delete({ + * secretId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: SecretDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.SecretService/DeleteSecret', { body, ...options }); @@ -141,6 +173,13 @@ export class Secrets extends APIResource { * ```yaml * secretId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const response = await client.secrets.getValue({ + * secretId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ getValue(body: SecretGetValueParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.SecretService/GetSecretValue', { body, ...options }); @@ -164,6 +203,14 @@ export class Secrets extends APIResource { * secretId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * value: "new-secret-value" * ``` + * + * @example + * ```ts + * const response = await client.secrets.updateValue({ + * secretId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * value: 'new-secret-value', + * }); + * ``` */ updateValue(body: SecretUpdateValueParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.SecretService/UpdateSecretValue', { body, ...options }); diff --git a/src/resources/shared.ts b/src/resources/shared.ts index d2f7c17..b3ed4ee 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Shared from './shared'; -import { EnvironmentClassesPage, TaskExecutionsPage, TasksPage } from '../core/pagination'; +import { EnvironmentClassesPage, GatewaysPage, TaskExecutionsPage, TasksPage } from '../core/pagination'; /** * An AutomationTrigger represents a trigger for an automation action. The @@ -79,6 +79,27 @@ export interface FieldValue { value?: string; } +/** + * Gateway represents a system gateway that provides access to services + */ +export interface Gateway { + /** + * name is the human-readable name of the gateway. name is unique across all + * gateways. + */ + name: string; + + /** + * url of the gateway + */ + url: string; + + /** + * region is the geographical region where the gateway is located + */ + region?: string; +} + export type OrganizationRole = | 'ORGANIZATION_ROLE_UNSPECIFIED' | 'ORGANIZATION_ROLE_ADMIN' @@ -90,7 +111,8 @@ export type Principal = | 'PRINCIPAL_USER' | 'PRINCIPAL_RUNNER' | 'PRINCIPAL_ENVIRONMENT' - | 'PRINCIPAL_SERVICE_ACCOUNT'; + | 'PRINCIPAL_SERVICE_ACCOUNT' + | 'PRINCIPAL_RUNNER_MANAGER'; export interface RunsOn { docker: RunsOn.Docker; @@ -353,3 +375,5 @@ export type TasksTasksPage = TasksPage; export type TaskExecutionsTaskExecutionsPage = TaskExecutionsPage; export type EnvironmentClassesEnvironmentClassesPage = EnvironmentClassesPage; + +export type GatewaysGatewaysPage = GatewaysPage; diff --git a/src/resources/usage.ts b/src/resources/usage.ts index 9417a8f..fa5f052 100644 --- a/src/resources/usage.ts +++ b/src/resources/usage.ts @@ -1,21 +1,21 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../core/resource'; -import { PagePromise, SessionsPage, type SessionsPageParams } from '../core/pagination'; +import { PagePromise, RecordsPage, type RecordsPageParams } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; export class Usage extends APIResource { /** - * Lists completed environment sessions within a specified date range. + * Lists completed environment runtime records within a specified date range. * - * Returns a list of environment sessions that were completed within the specified - * date range. Currently running sessions are not included. + * Returns a list of environment runtime records that were completed within the + * specified date range. Records of currently running environments are not + * included. * * Use this method to: * - * - View environment sessions + * - View environment runtime records * - Filter by project - * - Monitor session activity * - Create custom usage reports * * ### Example @@ -29,95 +29,118 @@ export class Usage extends APIResource { * pagination: * pageSize: 100 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const environmentUsageRecord of client.usage.listEnvironmentRuntimeRecords( + * { + * filter: { + * dateRange: { + * endTime: '2024-01-02T00:00:00Z', + * startTime: '2024-01-01T00:00:00Z', + * }, + * projectId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }, + * pagination: { pageSize: 100 }, + * }, + * )) { + * // ... + * } + * ``` */ - listEnvironmentSessions( - params: UsageListEnvironmentSessionsParams, + listEnvironmentRuntimeRecords( + params: UsageListEnvironmentRuntimeRecordsParams, options?: RequestOptions, - ): PagePromise { + ): PagePromise { const { token, pageSize, ...body } = params; return this._client.getAPIList( - '/gitpod.v1.UsageService/ListEnvironmentSessions', - SessionsPage, + '/gitpod.v1.UsageService/ListEnvironmentUsageRecords', + RecordsPage, { query: { token, pageSize }, body, method: 'post', ...options }, ); } } -export type EnvironmentSessionsSessionsPage = SessionsPage; +export type EnvironmentUsageRecordsRecordsPage = RecordsPage; -export interface EnvironmentSession { +/** + * EnvironmentUsageRecord represents a record of an environment from start to stop. + */ +export interface EnvironmentUsageRecord { /** - * Environment session ID. + * Environment usage record ID. */ id?: string; /** - * Time when the session was created. + * Time when the environment was created. */ createdAt?: string; /** - * Environment class ID associated with the session. + * Environment class ID associated with the record. */ environmentClassId?: string; /** - * Environment ID associated with the session. + * Environment ID associated with the record. */ environmentId?: string; /** - * Project ID associated with the session (if available). + * Project ID associated with the environment (if available). */ projectId?: string; /** - * Runner ID associated with the session. + * Runner ID associated with the environment. */ runnerId?: string; /** - * Time when the session was stopped. + * Time when the environment was stopped. */ stoppedAt?: string; /** - * User ID that created the session. + * User ID is the ID of the user who created the environment associated with the + * record. */ userId?: string; } -export interface UsageListEnvironmentSessionsParams extends SessionsPageParams { +export interface UsageListEnvironmentRuntimeRecordsParams extends RecordsPageParams { /** * Body param: Filter options. */ - filter?: UsageListEnvironmentSessionsParams.Filter; + filter?: UsageListEnvironmentRuntimeRecordsParams.Filter; /** * Body param: Pagination options. */ - pagination?: UsageListEnvironmentSessionsParams.Pagination; + pagination?: UsageListEnvironmentRuntimeRecordsParams.Pagination; } -export namespace UsageListEnvironmentSessionsParams { +export namespace UsageListEnvironmentRuntimeRecordsParams { /** * Filter options. */ export interface Filter { /** - * Date range to query sessions within. + * Date range to query runtime records within. */ dateRange: Filter.DateRange; /** - * Optional project ID to filter sessions by. + * Optional project ID to filter runtime records by. */ projectId?: string; } export namespace Filter { /** - * Date range to query sessions within. + * Date range to query runtime records within. */ export interface DateRange { /** @@ -152,8 +175,8 @@ export namespace UsageListEnvironmentSessionsParams { export declare namespace Usage { export { - type EnvironmentSession as EnvironmentSession, - type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage, - type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams, + type EnvironmentUsageRecord as EnvironmentUsageRecord, + type EnvironmentUsageRecordsRecordsPage as EnvironmentUsageRecordsRecordsPage, + type UsageListEnvironmentRuntimeRecordsParams as UsageListEnvironmentRuntimeRecordsParams, }; } diff --git a/src/resources/users/dotfiles.ts b/src/resources/users/dotfiles.ts index 7a69609..f3539f3 100644 --- a/src/resources/users/dotfiles.ts +++ b/src/resources/users/dotfiles.ts @@ -21,6 +21,11 @@ export class Dotfiles extends APIResource { * ```yaml * {} * ``` + * + * @example + * ```ts + * const dotfile = await client.users.dotfiles.get(); + * ``` */ get(body: DotfileGetParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.UserService/GetDotfilesConfiguration', { body, ...options }); @@ -51,6 +56,11 @@ export class Dotfiles extends APIResource { * ```yaml * {} * ``` + * + * @example + * ```ts + * const response = await client.users.dotfiles.set(); + * ``` */ set(body: DotfileSetParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.UserService/SetDotfilesConfiguration', { body, ...options }); diff --git a/src/resources/users/pats.ts b/src/resources/users/pats.ts index 6827d68..22e4c6b 100644 --- a/src/resources/users/pats.ts +++ b/src/resources/users/pats.ts @@ -32,6 +32,21 @@ export class Pats extends APIResource { * pagination: * pageSize: 20 * ``` + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const personalAccessToken of client.users.pats.list( + * { + * filter: { + * userIds: ['f53d2330-3795-4c5d-a1f3-453121af9c60'], + * }, + * pagination: { pageSize: 20 }, + * }, + * )) { + * // ... + * } + * ``` */ list( params: PatListParams, @@ -63,6 +78,14 @@ export class Pats extends APIResource { * ```yaml * personalAccessTokenId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const pat = await client.users.pats.delete({ + * personalAccessTokenId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ delete(body: PatDeleteParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.UserService/DeletePersonalAccessToken', { body, ...options }); @@ -86,6 +109,14 @@ export class Pats extends APIResource { * ```yaml * personalAccessTokenId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" * ``` + * + * @example + * ```ts + * const pat = await client.users.pats.get({ + * personalAccessTokenId: + * 'd2c94c27-3b76-4a42-b88c-95a85e392c68', + * }); + * ``` */ get(body: PatGetParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.UserService/GetPersonalAccessToken', { body, ...options }); diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts index 07f8eca..744a576 100644 --- a/src/resources/users/users.ts +++ b/src/resources/users/users.ts @@ -48,6 +48,11 @@ export class Users extends APIResource { * ```yaml * {} * ``` + * + * @example + * ```ts + * const response = await client.users.getAuthenticatedUser(); + * ``` */ getAuthenticatedUser( body: UserGetAuthenticatedUserParams, @@ -84,6 +89,13 @@ export class Users extends APIResource { * userId: "f53d2330-3795-4c5d-a1f3-453121af9c60" * suspended: false * ``` + * + * @example + * ```ts + * const response = await client.users.setSuspended({ + * userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60', + * }); + * ``` */ setSuspended(body: UserSetSuspendedParams, options?: RequestOptions): APIPromise { return this._client.post('/gitpod.v1.UserService/SetSuspended', { body, ...options }); diff --git a/tests/api-resources/accounts.test.ts b/tests/api-resources/accounts.test.ts index 85aed19..cb00eba 100644 --- a/tests/api-resources/accounts.test.ts +++ b/tests/api-resources/accounts.test.ts @@ -57,6 +57,18 @@ describe('resource accounts', () => { }); }); + // skipped: tests are disabled for the time being + test.skip('listJoinableOrganizations', async () => { + const responsePromise = client.accounts.listJoinableOrganizations({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + // skipped: tests are disabled for the time being test.skip('listLoginProviders', async () => { const responsePromise = client.accounts.listLoginProviders({}); diff --git a/tests/api-resources/environments/environments.test.ts b/tests/api-resources/environments/environments.test.ts index aaf1efc..52c663b 100644 --- a/tests/api-resources/environments/environments.test.ts +++ b/tests/api-resources/environments/environments.test.ts @@ -157,4 +157,16 @@ describe('resource environments', () => { expect(dataAndResponse.data).toBe(response); expect(dataAndResponse.response).toBe(rawResponse); }); + + // skipped: tests are disabled for the time being + test.skip('unarchive', async () => { + const responsePromise = client.environments.unarchive({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); }); diff --git a/tests/api-resources/gateways.test.ts b/tests/api-resources/gateways.test.ts new file mode 100644 index 0000000..94c06d6 --- /dev/null +++ b/tests/api-resources/gateways.test.ts @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Gitpod from '@gitpod/sdk'; + +const client = new Gitpod({ + bearerToken: 'My Bearer Token', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource gateways', () => { + // skipped: tests are disabled for the time being + test.skip('list', async () => { + const responsePromise = client.gateways.list({}); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); +}); diff --git a/tests/api-resources/organizations/policies.test.ts b/tests/api-resources/organizations/policies.test.ts index a0aba22..289b2ad 100644 --- a/tests/api-resources/organizations/policies.test.ts +++ b/tests/api-resources/organizations/policies.test.ts @@ -56,6 +56,7 @@ describe('resource policies', () => { maximumRunningEnvironmentsPerUser: '5', membersCreateProjects: true, membersRequireProjects: true, + portSharingDisabled: true, }); }); }); diff --git a/tests/api-resources/usage.test.ts b/tests/api-resources/usage.test.ts index 1d2b3dc..6ec2547 100644 --- a/tests/api-resources/usage.test.ts +++ b/tests/api-resources/usage.test.ts @@ -9,8 +9,8 @@ const client = new Gitpod({ describe('resource usage', () => { // skipped: tests are disabled for the time being - test.skip('listEnvironmentSessions', async () => { - const responsePromise = client.usage.listEnvironmentSessions({}); + test.skip('listEnvironmentRuntimeRecords', async () => { + const responsePromise = client.usage.listEnvironmentRuntimeRecords({}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; diff --git a/tests/index.test.ts b/tests/index.test.ts index afe3fed..e90aa8b 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -331,6 +331,82 @@ describe('instantiate client', () => { expect(client2.maxRetries).toEqual(2); }); + describe('withOptions', () => { + test('creates a new client with overridden options', () => { + const client = new Gitpod({ + baseURL: 'http://localhost:5000/', + maxRetries: 3, + bearerToken: 'My Bearer Token', + }); + + const newClient = client.withOptions({ + maxRetries: 5, + baseURL: 'http://localhost:5001/', + }); + + // Verify the new client has updated options + expect(newClient.maxRetries).toEqual(5); + expect(newClient.baseURL).toEqual('http://localhost:5001/'); + + // Verify the original client is unchanged + expect(client.maxRetries).toEqual(3); + expect(client.baseURL).toEqual('http://localhost:5000/'); + + // Verify it's a different instance + expect(newClient).not.toBe(client); + expect(newClient.constructor).toBe(client.constructor); + }); + + test('inherits options from the parent client', () => { + const client = new Gitpod({ + baseURL: 'http://localhost:5000/', + defaultHeaders: { 'X-Test-Header': 'test-value' }, + defaultQuery: { 'test-param': 'test-value' }, + bearerToken: 'My Bearer Token', + }); + + const newClient = client.withOptions({ + baseURL: 'http://localhost:5001/', + }); + + // Test inherited options remain the same + expect(newClient.buildURL('/foo', null)).toEqual('http://localhost:5001/foo?test-param=test-value'); + + const { req } = newClient.buildRequest({ path: '/foo', method: 'get' }); + expect(req.headers.get('x-test-header')).toEqual('test-value'); + }); + + test('respects runtime property changes when creating new client', () => { + const client = new Gitpod({ + baseURL: 'http://localhost:5000/', + timeout: 1000, + bearerToken: 'My Bearer Token', + }); + + // Modify the client properties directly after creation + client.baseURL = 'http://localhost:6000/'; + client.timeout = 2000; + + // Create a new client with withOptions + const newClient = client.withOptions({ + maxRetries: 10, + }); + + // Verify the new client uses the updated properties, not the original ones + expect(newClient.baseURL).toEqual('http://localhost:6000/'); + expect(newClient.timeout).toEqual(2000); + expect(newClient.maxRetries).toEqual(10); + + // Original client should still have its modified properties + expect(client.baseURL).toEqual('http://localhost:6000/'); + expect(client.timeout).toEqual(2000); + expect(client.maxRetries).not.toEqual(10); + + // Verify URL building uses the updated baseURL + expect(newClient.buildURL('/bar', null)).toEqual('http://localhost:6000/bar'); + }); + }); + test('with environment variable arguments', () => { // set options via env var process.env['GITPOD_API_KEY'] = 'My Bearer Token'; diff --git a/yarn.lock b/yarn.lock index 414e05d..a95c3a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -714,10 +714,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@pkgr/core@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" - integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@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" @@ -1623,13 +1623,13 @@ 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.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz#c4af01691a6fa9905207f0fbba0d7bea0902cce5" - integrity sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw== +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.9.1" + synckit "^0.11.7" eslint-plugin-unused-imports@^4.1.4: version "4.1.4" @@ -3317,13 +3317,12 @@ 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.8.8, synckit@^0.9.1: - version "0.8.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" - integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== +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.1.0" - tslib "^2.6.2" + "@pkgr/core" "^0.2.4" test-exclude@^6.0.0: version "6.0.0" @@ -3427,11 +3426,6 @@ tsconfig-paths@^4.0.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" From 3c6b1d33ef500d073008f79a05a58efe8aae6eb2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 08:19:29 +0000 Subject: [PATCH 45/46] feat(api): manual updates --- .stats.yml | 6 ++-- README.md | 38 ++++++++-------------- scripts/build | 2 -- src/client.ts | 8 ++--- src/core/pagination.ts | 2 +- src/internal/shim-types.d.ts | 28 ---------------- src/internal/shim-types.ts | 26 +++++++++++++++ src/internal/shims.ts | 4 +-- src/resources/environments/environments.ts | 9 ++++- 9 files changed, 57 insertions(+), 66 deletions(-) delete mode 100644 src/internal/shim-types.d.ts create mode 100644 src/internal/shim-types.ts diff --git a/.stats.yml b/.stats.yml index ac7c24e..d375176 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 119 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c850a6432597255fc1b788ba21a0494162e639f41dd80c0f9d07def239d31865.yml -openapi_spec_hash: fba3f62e51d3ba39eea280abe29f39f1 -config_hash: 8e3b8fba844b78950ad4a13b75b7fffc +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ca9a49ac7fbb63f55611fd7cd48a22a3ff8b38a797125c8513e891d9b7345550.yml +openapi_spec_hash: fd6ffbdfaefcc555e61ca1c565e05214 +config_hash: bb9d0a0bdadbee0985dd7c1e4f0e9e8a diff --git a/README.md b/README.md index 2121f11..31de3bb 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,9 @@ const client = new Gitpod({ bearerToken: process.env['GITPOD_API_KEY'], // This is the default and can be omitted }); -async function main() { - const response = await client.identity.getAuthenticatedIdentity(); +const response = await client.identity.getAuthenticatedIdentity(); - console.log(response.organizationId); -} - -main(); +console.log(response.organizationId); ``` ### Request & Response types @@ -47,12 +43,8 @@ const client = new Gitpod({ bearerToken: process.env['GITPOD_API_KEY'], // This is the default and can be omitted }); -async function main() { - const response: Gitpod.IdentityGetAuthenticatedIdentityResponse = - await client.identity.getAuthenticatedIdentity(); -} - -main(); +const response: Gitpod.IdentityGetAuthenticatedIdentityResponse = + await client.identity.getAuthenticatedIdentity(); ``` Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors. @@ -65,19 +57,15 @@ a subclass of `APIError` will be thrown: ```ts -async function main() { - const response = await client.identity.getAuthenticatedIdentity().catch(async (err) => { - if (err instanceof Gitpod.APIError) { - console.log(err.status); // 400 - console.log(err.name); // BadRequestError - console.log(err.headers); // {server: 'nginx', ...} - } else { - throw err; - } - }); -} - -main(); +const response = await client.identity.getAuthenticatedIdentity().catch(async (err) => { + if (err instanceof Gitpod.APIError) { + console.log(err.status); // 400 + console.log(err.name); // BadRequestError + console.log(err.headers); // {server: 'nginx', ...} + } else { + throw err; + } +}); ``` Error codes are as follows: diff --git a/scripts/build b/scripts/build index 3323742..1909619 100755 --- a/scripts/build +++ b/scripts/build @@ -37,8 +37,6 @@ npm exec tsc-multi # when building .mjs node scripts/utils/fix-index-exports.cjs cp tsconfig.dist-src.json dist/src/tsconfig.json -cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts -cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts node scripts/utils/postprocess-files.cjs diff --git a/src/client.ts b/src/client.ts index f6fcad0..ac677ba 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5,8 +5,8 @@ import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestIni import { uuid4 } from './internal/utils/uuid'; import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; -import { type Logger, type LogLevel, parseLogLevel } from './internal/utils/log'; -export type { Logger, LogLevel } from './internal/utils/log'; +import { type Logger, type LogLevel as LogLevelClient, parseLogLevel } from './internal/utils/log'; +export type { Logger, LogLevel as LogLevelClient } from './internal/utils/log'; import { castToError, isAbortError } from './internal/errors'; import type { APIResponseProps } from './internal/parse'; import { getPlatformHeaders } from './internal/detect-platform'; @@ -318,7 +318,7 @@ export interface ClientOptions { * * Defaults to process.env['GITPOD_LOG'] or 'warn' if it isn't set. */ - logLevel?: LogLevel | undefined; + logLevel?: LogLevelClient | undefined; /** * Set the logger. @@ -338,7 +338,7 @@ export class Gitpod { maxRetries: number; timeout: number; logger: Logger | undefined; - logLevel: LogLevel | undefined; + logLevel: LogLevelClient | undefined; fetchOptions: MergedRequestInit | undefined; private fetch: Fetch; diff --git a/src/core/pagination.ts b/src/core/pagination.ts index 1eaa5cb..77ed264 100644 --- a/src/core/pagination.ts +++ b/src/core/pagination.ts @@ -99,7 +99,7 @@ export class PagePromise< * console.log(item) * } */ - async *[Symbol.asyncIterator]() { + async *[Symbol.asyncIterator](): AsyncGenerator { const page = await this; for await (const item of page) { yield item; diff --git a/src/internal/shim-types.d.ts b/src/internal/shim-types.d.ts deleted file mode 100644 index fe48144..0000000 --- a/src/internal/shim-types.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -/** - * Shims for types that we can't always rely on being available globally. - * - * Note: these only exist at the type-level, there is no corresponding runtime - * version for any of these symbols. - */ - -/** - * In order to properly access the global `NodeJS` type, if it's available, we - * need to make use of declaration shadowing. Without this, any checks for the - * presence of `NodeJS.ReadableStream` will fail. - */ -declare namespace NodeJS { - interface ReadableStream {} -} - -type HasProperties = keyof T extends never ? false : true; - -// @ts-ignore -type _ReadableStream = - // @ts-ignore - HasProperties extends true ? NodeJS.ReadableStream : ReadableStream; - -// @ts-ignore -declare const _ReadableStream: unknown extends typeof ReadableStream ? never : typeof ReadableStream; -export { _ReadableStream as ReadableStream }; diff --git a/src/internal/shim-types.ts b/src/internal/shim-types.ts new file mode 100644 index 0000000..8ddf7b0 --- /dev/null +++ b/src/internal/shim-types.ts @@ -0,0 +1,26 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +/** + * Shims for types that we can't always rely on being available globally. + * + * Note: these only exist at the type-level, there is no corresponding runtime + * version for any of these symbols. + */ + +type NeverToAny = T extends never ? any : T; + +/** @ts-ignore */ +type _DOMReadableStream = globalThis.ReadableStream; + +/** @ts-ignore */ +type _NodeReadableStream = import('stream/web').ReadableStream; + +type _ConditionalNodeReadableStream = + typeof globalThis extends { ReadableStream: any } ? never : _NodeReadableStream; + +type _ReadableStream = NeverToAny< + | ([0] extends [1 & _DOMReadableStream] ? never : _DOMReadableStream) + | ([0] extends [1 & _ConditionalNodeReadableStream] ? never : _ConditionalNodeReadableStream) +>; + +export type { _ReadableStream as ReadableStream }; diff --git a/src/internal/shims.ts b/src/internal/shims.ts index 95b03fb..284d15c 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -7,8 +7,8 @@ * messages in cases where an environment isn't fully supported. */ -import { type Fetch } from './builtin-types'; -import { type ReadableStream } from './shim-types'; +import type { Fetch } from './builtin-types'; +import type { ReadableStream } from './shim-types'; export function getDefaultFetch(): Fetch { if (typeof fetch !== 'undefined') { diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts index 229ccb8..77e8304 100644 --- a/src/resources/environments/environments.ts +++ b/src/resources/environments/environments.ts @@ -1474,12 +1474,19 @@ export interface EnvironmentUpdateParams { */ environmentId?: string; - metadata?: unknown | null; + metadata?: EnvironmentUpdateParams.Metadata | null; spec?: EnvironmentUpdateParams.Spec | null; } export namespace EnvironmentUpdateParams { + export interface Metadata { + /** + * name is the user-defined display name of the environment + */ + name?: string | null; + } + export interface Spec { /** * automations_file is the automations file spec of the environment From 3d0b02ec694163de38f6242d045004b08dcecd5a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 08:20:02 +0000 Subject: [PATCH 46/46] release: 0.6.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 63 +++++++++++++++++++++++++++++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f1c1e58..bcd0522 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.0" + ".": "0.6.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index b82eb11..930b4e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,68 @@ # Changelog +## 0.6.0 (2025-06-06) + +Full Changelog: [v0.5.0...v0.6.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.5.0...v0.6.0) + +### Features + +* **api:** manual updates ([3c6b1d3](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/3c6b1d33ef500d073008f79a05a58efe8aae6eb2)) +* **api:** manual updates ([078548f](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/078548f4b1cd2101e258bd27c5c0fd5628566a88)) +* **api:** manual updates ([77b6f44](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/77b6f44b695808f66ce955683f86965c3b8605fb)) +* **api:** manual updates ([f0edc96](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/f0edc9696d24e0a4e4ed648b585883616cde251f)) +* **api:** manual updates ([f50f5ad](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/f50f5adf1ea13bb39845ff8644e2f670bc01856d)) + + +### Bug Fixes + +* **api:** improve type resolution when importing as a package ([#66](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/66)) ([8aa007b](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/8aa007bc39d87e8b96861748a23d4faa5d084c8a)) +* **client:** fix TypeError with undefined File ([#50](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/50)) ([1262a7b](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/1262a7bcd5e0619e1eaef399ee967b629c79ce09)) +* **client:** send `X-Stainless-Timeout` in seconds ([#63](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/63)) ([dab2433](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/dab243394f6b0f60cedc65f3eabcf1bfe64ed640)) +* **client:** send all configured auth headers ([#68](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/68)) ([3ced793](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/3ced7939c98da7bc8c42a457da3aee4510a778a7)) +* **exports:** ensure resource imports don't require /index ([#57](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/57)) ([23166e6](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/23166e607ec2b8915a97e974e09cdc0abdbc6c23)) +* **internal:** add mts file + crypto shim types ([#58](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/58)) ([716b94c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/716b94c4be5a42cfaf9f59fcdb9332b912113869)) +* **internal:** clean up undefined File test ([#51](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/51)) ([e1e0fb5](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e1e0fb509bfd526c9a8183480ad88330f0c7b240)) +* **internal:** fix file uploads in node 18 jest ([702757c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/702757cc250c54fa31731233f3b88841b42baa32)) +* **internal:** return in castToError instead of throwing ([#43](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/43)) ([2f70ad9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/2f70ad9e95854605f9f38c401d49f8422d62af75)) +* **mcp:** remove unused tools.ts ([#67](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/67)) ([65686bf](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/65686bf96f2a2147c620810605bc66876ec0c13e)) +* **tests:** manually reset node:buffer File ([#52](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/52)) ([2eded46](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/2eded46344af89fbaef371ab685056b8952aa946)) + + +### Chores + +* **ci:** add timeout thresholds for CI jobs ([d78258c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/d78258ce7b00f01f7714c59bda0d12d3f70b7ec3)) +* **ci:** only use depot for staging repos ([678516c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/678516c59e2a0a39caa817aa847f9a3f197172b7)) +* **client:** make jsonl methods consistent with other streaming methods ([#65](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/65)) ([62c4790](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/62c4790ed0515d7644fca6075b5d9304bd4b1642)) +* **client:** minor internal fixes ([e3c6fb8](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e3c6fb879bc94b55e66f65a5238102ba390387a8)) +* **client:** move misc public files to new `core/` directory, deprecate old paths ([#62](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/62)) ([e4008c3](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e4008c3ab36557410e2124287eb9ab861e5d81d2)) +* **client:** only accept standard types for file uploads ([#47](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/47)) ([cd888bc](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/cd888bc3c16d0d2cbf3b3c96ab23dc7d46360598)) +* **docs:** improve docs for withResponse/asResponse ([#54](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/54)) ([25092c5](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/25092c5070acc3602094bf34f304105cb7bd7157)) +* **exports:** cleaner resource index imports ([#60](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/60)) ([0049aac](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/0049aac07585fb4a1536ef6ff191b4ba5d5b9720)) +* **exports:** stop using path fallbacks ([#61](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/61)) ([a9df2c1](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/a9df2c166e44d19ff8b374e5225d29971c72bb3e)) +* **internal:** add aliases for Record and Array ([#64](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/64)) ([38e00c9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/38e00c9995d8528c361bf709d3951a0f00238ada)) +* **internal:** codegen related update ([e94c558](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e94c55895af8caf60720420c33c1e22c6e2d5bd4)) +* **internal:** codegen related update ([c60c38f](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/c60c38f7f805d86e56d6a2f96c742b1549d62e5c)) +* **internal:** codegen related update ([#55](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/55)) ([71a1bef](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/71a1bef58884eb34434a3e590cf0942c8166d33b)) +* **internal:** constrain synckit dev dependency ([#49](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/49)) ([41da630](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/41da630123709c225f8c173bbd2aace382d0e865)) +* **internal:** fix tests failing on node v18 ([#48](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/48)) ([c1031bd](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/c1031bd67090cc27d55472a5a32ee70df9ee781e)) +* **internal:** improve node 18 shims ([726127a](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/726127ae7ad639fc5587724e20559893ea3c67eb)) +* **internal:** minor client file refactoring ([#59](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/59)) ([51d47fd](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/51d47fd93e6be04336019ec05c60841a5d25195c)) +* **internal:** reduce CI branch coverage ([e8cd029](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e8cd029655896872fa1ccd8b71807f8c0ac565c9)) +* **internal:** refactor utils ([eafa310](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/eafa310bb3964addb8bbbf8c8811564f6985068e)) +* **internal:** remove extra empty newlines ([#56](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/56)) ([6431dc9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/6431dc9927a315b9faf1e906c95930bcec65f3d5)) +* **internal:** remove unnecessary todo ([#45](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/45)) ([bd9e536](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/bd9e5361115c7f9adc8c8d9798f38a04b55ab03c)) +* **internal:** share typescript helpers ([b52aa07](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/b52aa0747ab51dbdf0eeb63e3fce2c255f47a06c)) +* **internal:** upload builds and expand CI branch coverage ([dbd4446](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/dbd4446148041e01ec058c0a19568a17ad7384f7)) +* **perf:** faster base64 decoding ([b3a1e96](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/b3a1e96efe94fd726a49c050eb1a6e0069171983)) +* **tests:** improve enum examples ([#69](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/69)) ([af4a60a](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/af4a60aa5f1bc957cdb96b0996f4ee02c0d7d469)) +* **types:** improved go to definition on fetchOptions ([#53](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/53)) ([54a7db8](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/54a7db864f182bd872aeceae04747930a3e419a7)) + + +### Documentation + +* **readme:** fix typo ([fea4ecb](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/fea4ecb31efa7b73aec94c3aed1f574b80611110)) +* update URLs from stainlessapi.com to stainless.com ([#46](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/46)) ([6450e47](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/6450e47a5f12103274528a67028b91a01b9c55b8)) + ## 0.5.0 (2025-02-21) Full Changelog: [v0.4.0...v0.5.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.4.0...v0.5.0) diff --git a/package.json b/package.json index 8b673e5..445157f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gitpod/sdk", - "version": "0.5.0", + "version": "0.6.0", "description": "The official TypeScript library for the Gitpod API", "author": "Gitpod ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 1f5d158..30c2817 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.5.0'; // x-release-please-version +export const VERSION = '0.6.0'; // x-release-please-version