Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,3 @@ jobs:

- name: Run tests
run: ./scripts/test

2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.0.0-rc.5"
".": "1.0.0-rc.6"
}
4 changes: 3 additions & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
configured_endpoints: 5
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/grid%2Fspreadsheet-api-6e9b1263cf6d720224f647537949aef5bbf794efd14e08055bed7d31b523b0a8.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/grid%2Fspreadsheet-api-f9fd5fb43d56001ea7d7f49e92bd55134347b198b2664fd76321cc02a75817c9.yml
openapi_spec_hash: 5130b5ebb7cbfe7a906716c5cf21764b
config_hash: f5d6b47b28c650e373afc0eb0396899e
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## 1.0.0-rc.6 (2025-03-27)

Full Changelog: [v1.0.0-rc.5...v1.0.0-rc.6](https://github.com/GRID-is/api-sdk-ts/compare/v1.0.0-rc.5...v1.0.0-rc.6)

### Features

* **api:** api update ([#37](https://github.com/GRID-is/api-sdk-ts/issues/37)) ([78d193d](https://github.com/GRID-is/api-sdk-ts/commit/78d193d3d4619f1266ebedccbd3bc73c96e7fcc9))
* **api:** update API URL to api.grid.is ([#38](https://github.com/GRID-is/api-sdk-ts/issues/38)) ([bcc8f3c](https://github.com/GRID-is/api-sdk-ts/commit/bcc8f3c5c61e904e29dd0a7a3bf4de6b112e1729))


### Bug Fixes

* **internal:** add mts file + crypto shim types ([#33](https://github.com/GRID-is/api-sdk-ts/issues/33)) ([7ab8e1d](https://github.com/GRID-is/api-sdk-ts/commit/7ab8e1d00af0416eaa467c42be42a1960abc514a))


### Chores

* **client:** move misc public files to new `core/` directory, deprecate old paths ([#39](https://github.com/GRID-is/api-sdk-ts/issues/39)) ([80f0087](https://github.com/GRID-is/api-sdk-ts/commit/80f00879d13e20c34f51deebdc76f33ffff05634))
* **docs:** Update GRID app URL ([78f283f](https://github.com/GRID-is/api-sdk-ts/commit/78f283fd34f299634cd7755b886811191096045b))
* **exports:** cleaner resource index imports ([#35](https://github.com/GRID-is/api-sdk-ts/issues/35)) ([d8cbc61](https://github.com/GRID-is/api-sdk-ts/commit/d8cbc615cfa73a4d040ba0b3ef9a63312ba4f7f7))
* **exports:** stop using path fallbacks ([#36](https://github.com/GRID-is/api-sdk-ts/issues/36)) ([3ec3190](https://github.com/GRID-is/api-sdk-ts/commit/3ec3190e6113e5ba0e3e3e9bd13ed77387059a17))
* **internal:** codegen related update ([#31](https://github.com/GRID-is/api-sdk-ts/issues/31)) ([93391a0](https://github.com/GRID-is/api-sdk-ts/commit/93391a0a8513219fdf851d0913d16fe32114a318))
* **internal:** minor client file refactoring ([#34](https://github.com/GRID-is/api-sdk-ts/issues/34)) ([f45db71](https://github.com/GRID-is/api-sdk-ts/commit/f45db71123d330d8fd065d50e3d4888d6ba422d1))
* **internal:** remove extra empty newlines ([#32](https://github.com/GRID-is/api-sdk-ts/issues/32)) ([7128673](https://github.com/GRID-is/api-sdk-ts/commit/7128673f7fc7dac02c8884875b95da2c7ff67986))


### Documentation

* Explain how to use the API key ([3f67855](https://github.com/GRID-is/api-sdk-ts/commit/3f67855e034df13f465372a83c66386375bf0fff))

## 1.0.0-rc.5 (2025-03-07)

Full Changelog: [v1.0.0-rc.4...v1.0.0-rc.5](https://github.com/GRID-is/api-sdk-ts/compare/v1.0.0-rc.4...v1.0.0-rc.5)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ You can use the `maxRetries` option to configure or disable this:
// Configure the default for all requests:
const client = new Grid({
maxRetries: 0, // default is 2
apiKey: 'My API Key',
});

// Or, configure per-request:
Expand All @@ -155,6 +156,7 @@ Requests time out after one minute by default. You can configure this with a `ti
// Configure the default for all requests:
const client = new Grid({
timeout: 20 * 1000, // 20 seconds (default is 1 minute)
apiKey: 'My API Key',
});

// Override per-request:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@grid-is/api",
"version": "1.0.0-rc.5",
"version": "1.0.0-rc.6",
"description": "The official TypeScript library for the Grid API",
"author": "Grid <info@grid.is>",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 3 additions & 8 deletions scripts/build
Original file line number Diff line number Diff line change
Expand Up @@ -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 = Grid 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

Expand Down
8 changes: 4 additions & 4 deletions scripts/utils/postprocess-files.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
94 changes: 2 additions & 92 deletions src/api-promise.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,2 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import { type Grid } 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<T> extends Promise<T> {
private parsedPromise: Promise<T> | undefined;
#client: Grid;

constructor(
client: Grid,
private responsePromise: Promise<APIResponseProps>,
private parseResponse: (
client: Grid,
props: APIResponseProps,
) => PromiseOrValue<T> = 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<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
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<Response> {
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<T> {
if (!this.parsedPromise) {
this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
}
return this.parsedPromise;
}

override then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
): Promise<TResult1 | TResult2> {
return this.parse().then(onfulfilled, onrejected);
}

override catch<TResult = never>(
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
): Promise<T | TResult> {
return this.parse().catch(onrejected);
}

override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
return this.parse().finally(onfinally);
}
}
/** @deprecated Import from ./core/api-promise instead */
export * from './core/api-promise';
69 changes: 11 additions & 58 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
// 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';
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 { AbstractPage, type CursorPaginationParams, CursorPaginationResponse } from './pagination';
import * as Uploads from './uploads';
import * as Errors from './core/error';
import * as Pagination from './core/pagination';
import { AbstractPage, type CursorPaginationParams, CursorPaginationResponse } 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';
Expand All @@ -36,48 +38,6 @@ import { readEnv } from './internal/utils/env';
import { formatRequestDetails, loggerFor } from './internal/utils/log';
import { isEmptyObj } from './internal/utils/values';

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: Grid,
): LogLevel | undefined => {
if (!maybeLevel) {
return undefined;
}
const levels: Record<LogLevel, true> = {
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 {
/**
* Bearer token used for authentication with the API
Expand Down Expand Up @@ -151,8 +111,6 @@ export interface ClientOptions {
logger?: Logger | undefined;
}

type FinalizedRequestInit = RequestInit & { headers: Headers };

/**
* API Client for interfacing with the Grid API.
*/
Expand All @@ -175,7 +133,7 @@ export class Grid {
* API Client for interfacing with the Grid API.
*
* @param {string | undefined} [opts.apiKey=process.env['GRID_API_TOKEN'] ?? undefined]
* @param {string} [opts.baseURL=process.env['GRID_BASE_URL'] ?? https://api-alpha.grid.is] - Override the default base URL for the API.
* @param {string} [opts.baseURL=process.env['GRID_BASE_URL'] ?? https://api.grid.is] - Override the default base URL for the API.
* @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
* @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
* @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
Expand All @@ -197,7 +155,7 @@ export class Grid {
const options: ClientOptions = {
apiKey,
...opts,
baseURL: baseURL || `https://api-alpha.grid.is`,
baseURL: baseURL || `https://api.grid.is`,
};

this.baseURL = options.baseURL!;
Expand Down Expand Up @@ -228,10 +186,6 @@ export class Grid {
return;
}

protected authHeaders(opts: FinalRequestOptions): Headers | undefined {
return new Headers({ Authorization: `Bearer ${this.apiKey}` });
}

/**
* Basic re-implementation of `qs.stringify` for primitive types.
*/
Expand Down Expand Up @@ -682,7 +636,6 @@ export class Grid {
...getPlatformHeaders(),
'X-Client-Name': 'api-sdk',
},
this.authHeaders(options),
this._options.defaultHeaders,
bodyHeaders,
options.headers,
Expand Down
3 changes: 3 additions & 0 deletions src/core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `core`

This directory holds public modules implementing non-resource-specific SDK functionality.
Loading