diff --git a/.changeset/tame-rules-wash.md b/.changeset/tame-rules-wash.md new file mode 100644 index 000000000..c6c4860c5 --- /dev/null +++ b/.changeset/tame-rules-wash.md @@ -0,0 +1,5 @@ +--- +"@osdk/oauth": minor +--- + +Adds createConfidentialOauthClient diff --git a/docs/vite.md b/docs/vite.md new file mode 100644 index 000000000..8254073dc --- /dev/null +++ b/docs/vite.md @@ -0,0 +1,24 @@ +# Using OSDK with Vite + +## Fixing common problems + +### "ReferenceError: process is not defined" + +The OSDK related libraries leverage a long standing convention to use `process.env.NODE_ENV` to determine the level of verbosity for `console.log`/`console.warn`/`console.error` and to create optimized production code. + +Recent versions of Vite have begun pushing developers to use `import.meta.env` instead of `process.env` which is a noble change with good intentions but one that creates problems for library authors trying to support multiple bundling frameworks. + +Out of the box, Vite will not perform the required replacement to optimize the code which leads to `process` being undefined and a runtime error for you. This can be worked around by updating your Vite config to process the replacement: + +```ts +// ... +export default defineConfig(({ mode }) => { + // ... + return { + define: { + "process.env.NODE_ENV": JSON.stringify(mode) + }, + // ... + } +} +``` diff --git a/packages/client/src/createPlatformClient.ts b/packages/client/src/createPlatformClient.ts index 59edfca09..beb162031 100644 --- a/packages/client/src/createPlatformClient.ts +++ b/packages/client/src/createPlatformClient.ts @@ -14,9 +14,12 @@ * limitations under the License. */ +import type { SharedClientContext } from "@osdk/shared.client"; import { createSharedClientContext } from "@osdk/shared.client.impl"; import { USER_AGENT } from "./util/UserAgent.js"; +export interface PlatformClient extends SharedClientContext {} + /** * Creates a client that can only be used with Platform APIs. * @@ -34,7 +37,7 @@ export function createPlatformClient( tokenProvider: () => Promise, options: undefined = undefined, fetchFn: typeof globalThis.fetch = fetch, -) { +): PlatformClient { return createSharedClientContext( baseUrl, tokenProvider, diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 7c9b9947e..e066c0686 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -31,12 +31,11 @@ export type { } from "@osdk/client.api"; export { PalantirApiError } from "@osdk/shared.net.errors"; +export { ActionValidationError } from "./actions/ActionValidationError.js"; export type { Client } from "./Client.js"; +export { createAttachmentFromRid } from "./createAttachmentFromRid.js"; export { createClient } from "./createClient.js"; export { createPlatformClient } from "./createPlatformClient.js"; - -export { createAttachmentFromRid } from "./createAttachmentFromRid.js"; - -export { ActionValidationError } from "./actions/ActionValidationError.js"; +export type { PlatformClient } from "./createPlatformClient.js"; export { isOk } from "./ResultOrError.js"; export type { ResultOrError } from "./ResultOrError.js"; diff --git a/packages/e2e.sandbox.oauth/bin/testConfidentialClientNode.mjs b/packages/e2e.sandbox.oauth/bin/testConfidentialClientNode.mjs new file mode 100755 index 000000000..09295a6d5 --- /dev/null +++ b/packages/e2e.sandbox.oauth/bin/testConfidentialClientNode.mjs @@ -0,0 +1,4 @@ +#!/usr/bin/env node +import { testConfidentialClientNode } from "../build/esm/index.js"; + +testConfidentialClientNode(); diff --git a/packages/e2e.sandbox.oauth/package.json b/packages/e2e.sandbox.oauth/package.json new file mode 100644 index 000000000..21c9668e5 --- /dev/null +++ b/packages/e2e.sandbox.oauth/package.json @@ -0,0 +1,59 @@ +{ + "name": "@osdk/e2e.sandbox.oauth", + "private": true, + "version": "0.0.0", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/palantir/osdk-ts.git" + }, + "exports": { + ".": { + "require": "./build/cjs/index.cjs", + "browser": "./build/browser/index.js", + "import": "./build/esm/index.js" + }, + "./*": { + "require": "./build/cjs/public/*.cjs", + "browser": "./build/browser/public/*.js", + "import": "./build/esm/public/*.js" + } + }, + "scripts": { + "check-attw": "monorepo.tool.attw both", + "check-spelling": "cspell --quiet .", + "clean": "rm -rf lib dist types build tsconfig.tsbuildinfo", + "fix-lint": "eslint . --fix && dprint fmt --config $(find-up dprint.json)", + "lint": "eslint . && dprint check --config $(find-up dprint.json)", + "transpile": "monorepo.tool.transpile", + "typecheck": "monorepo.tool.typecheck both" + }, + "dependencies": { + "@osdk/client": "workspace:~", + "@osdk/oauth": "workspace:~", + "consola": "^3.2.3", + "tiny-invariant": "^1.3.3" + }, + "devDependencies": { + "@osdk/monorepo.api-extractor": "workspace:~", + "@osdk/monorepo.tsconfig": "workspace:~", + "@osdk/monorepo.tsup": "workspace:~", + "typescript": "^5.5.2" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "build/cjs", + "build/esm", + "build/browser", + "CHANGELOG.md", + "package.json", + "templates", + "*.d.ts" + ], + "main": "./build/cjs/index.cjs", + "module": "./build/esm/index.js", + "types": "./build/cjs/index.d.cts", + "type": "module" +} diff --git a/packages/e2e.sandbox.oauth/src/index.ts b/packages/e2e.sandbox.oauth/src/index.ts new file mode 100644 index 000000000..a99acf91d --- /dev/null +++ b/packages/e2e.sandbox.oauth/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { testConfidentialClientNode } from "./testConfidentialClientNode.js"; diff --git a/packages/e2e.sandbox.oauth/src/testConfidentialClientNode.ts b/packages/e2e.sandbox.oauth/src/testConfidentialClientNode.ts new file mode 100644 index 000000000..57e75fe11 --- /dev/null +++ b/packages/e2e.sandbox.oauth/src/testConfidentialClientNode.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createConfidentialOauthClient } from "@osdk/oauth"; +import consola from "consola"; +import invariant from "tiny-invariant"; + +declare const process: { + env: Record; +}; + +export async function testConfidentialClientNode() { + const prefix = "TS_OSDK_E2E_OAUTH_CONFIDENTIAL_"; + const FOUNDRY_CLIENT_ID = process.env[`${prefix}FOUNDRY_CLIENT_ID`]; + const FOUNDRY_URL = process.env[`${prefix}FOUNDRY_URL`]; + const FOUNDRY_CLIENT_SECRET = process.env[`${prefix}FOUNDRY_CLIENT_SECRET`]; + + invariant( + FOUNDRY_CLIENT_ID != null, + `${prefix}FOUNDRY_CLIENT_ID is required`, + ); + invariant( + FOUNDRY_URL != null, + `${prefix}FOUNDRY_URL is required`, + ); + invariant( + FOUNDRY_CLIENT_SECRET != null, + `${prefix}FOUNDRY_URL is required`, + ); + + const auth = createConfidentialOauthClient( + FOUNDRY_CLIENT_ID, + FOUNDRY_CLIENT_SECRET, + FOUNDRY_URL, + ); + + const token = await auth(); + invariant( + token != null && token.length > 0, + "token should have been received", + ); + consola.log(token); +} diff --git a/packages/e2e.sandbox.oauth/tsconfig.cjs.json b/packages/e2e.sandbox.oauth/tsconfig.cjs.json new file mode 100644 index 000000000..3e2ecf7d1 --- /dev/null +++ b/packages/e2e.sandbox.oauth/tsconfig.cjs.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "CommonJS", + "moduleResolution": "Node", + "target": "ES6", + "rootDir": "src", + "outDir": "build/cjs" + }, + "include": [ + "./src/**/*" + ], + "references": [] +} diff --git a/packages/e2e.sandbox.oauth/tsconfig.json b/packages/e2e.sandbox.oauth/tsconfig.json new file mode 100644 index 000000000..6c1ec6f17 --- /dev/null +++ b/packages/e2e.sandbox.oauth/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@osdk/monorepo.tsconfig/base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esm" + }, + "include": [ + "./src/**/*" + ], + "references": [] +} diff --git a/packages/e2e.sandbox.oauth/tsup.config.js b/packages/e2e.sandbox.oauth/tsup.config.js new file mode 100644 index 000000000..7a77e08bc --- /dev/null +++ b/packages/e2e.sandbox.oauth/tsup.config.js @@ -0,0 +1,21 @@ +/* + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineConfig } from "tsup"; + +export default defineConfig(async (options) => + (await import("@osdk/monorepo.tsup")).default(options, {}) +); diff --git a/packages/e2e.sandbox.todoapp/vite.config.mts b/packages/e2e.sandbox.todoapp/vite.config.mts index 05f45701b..a1e11ed87 100644 --- a/packages/e2e.sandbox.todoapp/vite.config.mts +++ b/packages/e2e.sandbox.todoapp/vite.config.mts @@ -9,6 +9,9 @@ export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); return { + define: { + "process.env.NODE_ENV": JSON.stringify(mode), + }, plugins: [ react(), visualizer({ @@ -25,6 +28,12 @@ export default defineConfig(({ mode }) => { "/object-set-service": `${env.VITE_FOUNDRY_URL}`, }, }, + optimizeDeps: { + // shared.client is a mixed package that needs to be properly processed by vite + // but normally linked packages do not get that treatment so we have to explicitly add it here + // and in the `commonjsOptions` below + include: ["@osdk/client > @osdk/shared.client"], + }, build: { outDir: "build/site/", }, diff --git a/packages/oauth/package.json b/packages/oauth/package.json index 409e673ab..205187ffb 100644 --- a/packages/oauth/package.json +++ b/packages/oauth/package.json @@ -36,7 +36,6 @@ "@osdk/monorepo.tsconfig": "workspace:~", "@osdk/monorepo.tsup": "workspace:~", "jest-extended": "^4.0.2", - "ts-expect": "^1.3.0", "typescript": "^5.5.2" }, "publishConfig": { diff --git a/packages/oauth/src/BaseOauthClient.ts b/packages/oauth/src/BaseOauthClient.ts new file mode 100644 index 000000000..1f91140d3 --- /dev/null +++ b/packages/oauth/src/BaseOauthClient.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Token } from "./Token.js"; + +export type Events = { + signIn: CustomEvent; + signOut: Event; + refresh: CustomEvent; +}; + +export interface BaseOauthClient { + (): Promise; + + signIn: () => Promise; + signOut: () => Promise; + + addEventListener: ( + type: T, + listener: ((evt: Events[T]) => void) | null, + options?: boolean | AddEventListenerOptions, + ) => void; + + removeEventListener: ( + type: T, + callback: ((evt: Events[T]) => void) | null, + options?: EventListenerOptions | boolean, + ) => void; +} diff --git a/packages/oauth/src/ConfidentialOauthClient.ts b/packages/oauth/src/ConfidentialOauthClient.ts new file mode 100644 index 000000000..4672de2d0 --- /dev/null +++ b/packages/oauth/src/ConfidentialOauthClient.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BaseOauthClient } from "./BaseOauthClient.js"; + +export interface ConfidentialOauthClient + extends BaseOauthClient<"signIn" | "signOut"> +{ +} diff --git a/packages/oauth/src/PublicOauthClient.ts b/packages/oauth/src/PublicOauthClient.ts index 72fa1cff4..1c921b448 100644 --- a/packages/oauth/src/PublicOauthClient.ts +++ b/packages/oauth/src/PublicOauthClient.ts @@ -14,30 +14,11 @@ * limitations under the License. */ +import type { BaseOauthClient } from "./BaseOauthClient.js"; import type { Token } from "./Token.js"; -export type Events = { - signIn: CustomEvent; - signOut: Event; - refresh: CustomEvent; -}; - -export interface PublicOauthClient { - (): Promise; - - signIn: () => Promise; +export interface PublicOauthClient + extends BaseOauthClient<"signIn" | "signOut" | "refresh"> +{ refresh: () => Promise; - signOut: () => Promise; - - addEventListener: ( - type: T, - listener: ((evt: Events[T]) => void) | null, - options?: boolean | AddEventListenerOptions, - ) => void; - - removeEventListener: ( - type: T, - callback: ((evt: Events[T]) => void) | null, - options?: EventListenerOptions | boolean, - ) => void; } diff --git a/packages/oauth/src/common.ts b/packages/oauth/src/common.ts new file mode 100644 index 000000000..d5e9bbb4d --- /dev/null +++ b/packages/oauth/src/common.ts @@ -0,0 +1,237 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + AuthorizationServer, + Client, + HttpRequestOptions, + OAuth2TokenEndpointResponse, +} from "oauth4webapi"; +import { processRevocationResponse, revocationRequest } from "oauth4webapi"; +import invariant from "tiny-invariant"; +import { TypedEventTarget } from "typescript-event-target"; +import type { BaseOauthClient, Events } from "./BaseOauthClient.js"; +import { throwIfError } from "./throwIfError.js"; +import type { Token } from "./Token.js"; + +// Node 18 is supposed to have a `CustomEvent` but it is not exposed on `globalThis` +// which creates a problem for making a single codebase for node and browser. This polyfill works around it +const CustomEvent = process.env.target === "browser" + ? globalThis.CustomEvent + : globalThis.CustomEvent + ?? class CustomEvent extends Event { + #detail: T | null; + + constructor(type: string, options: EventInit & { detail: T }) { + super(type, options); + this.#detail = options?.detail ?? null; + } + + get detail() { + return this.#detail; + } + }; + +declare const process: { + env: Record; +}; + +const localStorage = globalThis.localStorage; + +type LocalStorageState = + // when we are going to the login page + | { + refresh_token?: never; + codeVerifier?: never; + state?: never; + oldUrl: string; + } + // when we are redirecting to oauth login + | { + refresh_token?: never; + codeVerifier: string; + state: string; + oldUrl: string; + } + // when we have the refresh token + | { + refresh_token?: string; + codeVerifier?: never; + state?: never; + oldUrl?: never; + } + | { + refresh_token?: never; + codeVerifier?: never; + state?: never; + oldUrl?: never; + }; + +export function saveLocal(client: Client, x: LocalStorageState) { + // MUST `localStorage?` as nodejs does not have localStorage + localStorage?.setItem( + `@osdk/oauth : refresh : ${client.client_id}`, + JSON.stringify(x), + ); +} + +export function removeLocal(client: Client) { + // MUST `localStorage?` as nodejs does not have localStorage + localStorage?.removeItem(`@osdk/oauth : refresh : ${client.client_id}`); +} + +export function readLocal(client: Client): LocalStorageState { + return JSON.parse( + // MUST `localStorage?` as nodejs does not have localStorage + localStorage?.getItem(`@osdk/oauth : refresh : ${client.client_id}`) + ?? "{}", + ); +} + +export function common< + R extends undefined | (() => Promise), +>( + client: Client, + as: AuthorizationServer, + _signIn: () => Promise, + oauthHttpOptions: HttpRequestOptions, + refresh: R, +): { + getToken: BaseOauthClient & { refresh: R }; + makeTokenAndSaveRefresh: ( + resp: OAuth2TokenEndpointResponse, + type: "signIn" | "refresh", + ) => Token; +} { + let token: Token | undefined; + const eventTarget = new TypedEventTarget(); + + function makeTokenAndSaveRefresh( + resp: OAuth2TokenEndpointResponse, + type: "signIn" | "refresh", + ): Token { + const { refresh_token, expires_in, access_token } = resp; + invariant(expires_in != null); + saveLocal(client, { refresh_token }); + token = { + refresh_token, + expires_in, + access_token, + expires_at: Date.now() + expires_in * 1000, + }; + + eventTarget.dispatchTypedEvent( + type, + new CustomEvent( + type, + { detail: token }, + ), + ); + return token; + } + + let refreshTimeout: ReturnType; + function rmTimeout() { + if (refreshTimeout) clearTimeout(refreshTimeout); + } + function restartRefreshTimer(evt: CustomEvent) { + if (refresh) { + rmTimeout(); + refreshTimeout = setTimeout( + refresh, + evt.detail.expires_in * 1000 - 60 * 1000, + ); + } + } + + async function signOut() { + invariant(token, "not signed in"); + + const result = await processRevocationResponse( + await revocationRequest( + as, + client, + token.access_token, + oauthHttpOptions, + ), + ); + + rmTimeout(); + + // Clean up + removeLocal(client); + token = undefined; + throwIfError(result); + eventTarget.dispatchTypedEvent("signOut", new Event("signOut")); + } + + let pendingSignIn: Promise | undefined; + async function signIn() { + if (pendingSignIn) { + return pendingSignIn; + } + try { + pendingSignIn = _signIn(); + return await pendingSignIn; + } finally { + pendingSignIn = undefined; + } + } + + eventTarget.addEventListener("signIn", restartRefreshTimer); + eventTarget.addEventListener("refresh", restartRefreshTimer); + + const getToken = Object.assign(async function getToken() { + if (!token || Date.now() >= token.expires_at) { + token = await signIn(); + } + return token!.access_token; + }, { + signIn, + refresh, + signOut, + rmTimeout, + addEventListener: eventTarget.addEventListener.bind( + eventTarget, + ) as typeof eventTarget.addEventListener, + removeEventListener: eventTarget.removeEventListener.bind( + eventTarget, + ) as typeof eventTarget.removeEventListener, + }); + + return { getToken, makeTokenAndSaveRefresh }; +} + +export function createAuthorizationServer( + ctxPath: string, + url: string, +): Required< + Pick< + AuthorizationServer, + | "issuer" + | "token_endpoint" + | "authorization_endpoint" + | "revocation_endpoint" + > +> { + const issuer = `${new URL(ctxPath, url)}`; + return { + token_endpoint: `${issuer}/api/oauth2/token`, + authorization_endpoint: `${issuer}/api/oauth2/authorize`, + revocation_endpoint: `${issuer}/api/oauth2/revoke_token`, + issuer, + }; +} diff --git a/packages/oauth/src/createConfidentialOauthClient.ts b/packages/oauth/src/createConfidentialOauthClient.ts new file mode 100644 index 000000000..83196f218 --- /dev/null +++ b/packages/oauth/src/createConfidentialOauthClient.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2024 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Client, HttpRequestOptions } from "oauth4webapi"; +import { + clientCredentialsGrantRequest, + customFetch, + processClientCredentialsResponse, +} from "oauth4webapi"; +import { common, createAuthorizationServer } from "./common.js"; +import type { ConfidentialOauthClient } from "./ConfidentialOauthClient.js"; +import { throwIfError } from "./throwIfError.js"; + +/** + * @param client_id + * @param client_secret + * @param url the base url of your foundry server + * @param scopes + * @param fetchFn + * @param ctxPath + * @returns which can be used as a token provider + */ +export function createConfidentialOauthClient( + client_id: string, + client_secret: string, + url: string, + scopes: string[] = ["api:read-data", "api:write-data"], + fetchFn: typeof globalThis.fetch = globalThis.fetch, + ctxPath: string = "/multipass", +): ConfidentialOauthClient { + const client: Client = { client_id, client_secret }; + const authServer = createAuthorizationServer(ctxPath, url); + const oauthHttpOptions: HttpRequestOptions = { [customFetch]: fetchFn }; + + const { getToken, makeTokenAndSaveRefresh } = common( + client, + authServer, + _signIn, + oauthHttpOptions, + undefined, + ); + + async function _signIn() { + return makeTokenAndSaveRefresh( + throwIfError( + await processClientCredentialsResponse( + authServer, + client, + await clientCredentialsGrantRequest( + authServer, + client, + new URLSearchParams({ scope: scopes.join(" ") }), + oauthHttpOptions, + ), + ), + ), + "signIn", + ); + } + + return getToken; +} diff --git a/packages/oauth/src/createPublicOauthClient.ts b/packages/oauth/src/createPublicOauthClient.ts index 5a41a8f15..2f55051f4 100644 --- a/packages/oauth/src/createPublicOauthClient.ts +++ b/packages/oauth/src/createPublicOauthClient.ts @@ -15,12 +15,7 @@ */ import delay from "delay"; -import type { - AuthorizationServer, - Client, - HttpRequestOptions, - OAuth2TokenEndpointResponse, -} from "oauth4webapi"; +import type { Client, HttpRequestOptions } from "oauth4webapi"; import { authorizationCodeGrantRequest, calculatePKCECodeChallenge, @@ -28,64 +23,26 @@ import { generateRandomCodeVerifier, generateRandomState, processAuthorizationCodeOAuth2Response, - processRevocationResponse, refreshTokenGrantRequest, - revocationRequest, validateAuthResponse, } from "oauth4webapi"; -import invariant from "tiny-invariant"; -import { TypedEventTarget } from "typescript-event-target"; -import type { Events, PublicOauthClient } from "./PublicOauthClient.js"; +import { + common, + createAuthorizationServer, + readLocal, + removeLocal, + saveLocal, +} from "./common.js"; +import type { PublicOauthClient } from "./PublicOauthClient.js"; import { throwIfError } from "./throwIfError.js"; import type { Token } from "./Token.js"; -const storageKey = "asdfasdfdhjlkajhgj"; - declare const process: undefined | { env?: { NODE_ENV: "production" | "development"; }; }; -type LocalStorageState = - // when we are going to the login page - | { - refresh_token?: never; - codeVerifier?: never; - state?: never; - oldUrl: string; - } - // when we are redirecting to oauth login - | { - refresh_token?: never; - codeVerifier: string; - state: string; - oldUrl: string; - } - // when we have the refresh token - | { - refresh_token?: string; - codeVerifier?: never; - state?: never; - oldUrl?: never; - } - | { - refresh_token?: never; - codeVerifier?: never; - state?: never; - oldUrl?: never; - }; - -function saveLocal(x: LocalStorageState) { - localStorage.setItem(storageKey, JSON.stringify(x)); -} -function removeLocal() { - localStorage.removeItem(storageKey); -} -function readLocal(): LocalStorageState { - return JSON.parse(localStorage.getItem(storageKey) ?? "{}"); -} - /** * @param client_id * @param url the base url of your foundry server @@ -109,19 +66,17 @@ export function createPublicOauthClient( fetchFn: typeof globalThis.fetch = globalThis.fetch, ctxPath: string = "/multipass", ): PublicOauthClient { + const client: Client = { client_id, token_endpoint_auth_method: "none" }; + const authServer = createAuthorizationServer(ctxPath, url); const oauthHttpOptions: HttpRequestOptions = { [customFetch]: fetchFn }; - const eventTarget = new TypedEventTarget(); - const issuer = `${new URL(ctxPath, url)}`; - - const as: AuthorizationServer = { - token_endpoint: `${issuer}/api/oauth2/token`, - authorization_endpoint: `${issuer}/api/oauth2/authorize`, - revocation_endpoint: `${issuer}/api/oauth2/revoke_token`, - issuer, - }; - - const client: Client = { client_id, token_endpoint_auth_method: "none" }; + const { makeTokenAndSaveRefresh, getToken } = common( + client, + authServer, + _signIn, + oauthHttpOptions, + maybeRefresh.bind(globalThis, true), + ); async function go(x: string) { if (useHistory) return window.history.replaceState({}, "", x); @@ -131,29 +86,10 @@ export function createPublicOauthClient( throw new Error("Unable to redirect"); } - function makeTokenAndSaveRefresh( - resp: OAuth2TokenEndpointResponse, - type: "signIn" | "refresh", - ): Token { - const { refresh_token, expires_in, access_token } = resp; - invariant(expires_in != null); - saveLocal({ refresh_token }); - token = { - refresh_token, - expires_in, - access_token, - expires_at: Date.now() + expires_in * 1000, - }; - - eventTarget.dispatchTypedEvent( - type, - new CustomEvent(type, { detail: token }), - ); - return token; - } - - async function maybeRefresh(expectRefreshToken?: boolean) { - const { refresh_token } = readLocal(); + async function maybeRefresh( + expectRefreshToken?: boolean, + ): Promise { + const { refresh_token } = readLocal(client); if (!refresh_token) { if (expectRefreshToken) throw new Error("No refresh token found"); return; @@ -165,10 +101,10 @@ export function createPublicOauthClient( return makeTokenAndSaveRefresh( throwIfError( await processAuthorizationCodeOAuth2Response( - as, + authServer, client, await refreshTokenGrantRequest( - as, + authServer, client, refresh_token, oauthHttpOptions, @@ -185,7 +121,7 @@ export function createPublicOauthClient( e, ); } - removeLocal(); + removeLocal(client); if (expectRefreshToken) { throw new Error("Could not refresh token"); } @@ -193,21 +129,21 @@ export function createPublicOauthClient( } async function maybeHandleAuthReturn() { - const { codeVerifier, state, oldUrl } = readLocal(); + const { codeVerifier, state, oldUrl } = readLocal(client); if (!codeVerifier) return; try { const ret = makeTokenAndSaveRefresh( throwIfError( await processAuthorizationCodeOAuth2Response( - as, + authServer, client, await authorizationCodeGrantRequest( - as, + authServer, client, throwIfError( validateAuthResponse( - as, + authServer, client, new URL(window.location.href), state, @@ -232,22 +168,22 @@ export function createPublicOauthClient( e, ); } - removeLocal(); + removeLocal(client); } } async function initiateLoginRedirect(): Promise { if (loginPage && window.location.href !== loginPage) { - saveLocal({ oldUrl: postLoginPage }); + saveLocal(client, { oldUrl: postLoginPage }); return await go(loginPage); } const state = generateRandomState()!; const codeVerifier = generateRandomCodeVerifier(); - const oldUrl = readLocal().oldUrl ?? window.location.toString(); - saveLocal({ codeVerifier, state, oldUrl }); + const oldUrl = readLocal(client).oldUrl ?? window.location.toString(); + saveLocal(client, { codeVerifier, state, oldUrl }); - window.location.assign(`${as + window.location.assign(`${authServer .authorization_endpoint!}?${new URLSearchParams({ client_id, response_type: "code", @@ -263,83 +199,15 @@ export function createPublicOauthClient( throw new Error("Unable to redirect"); } - let refreshTimeout: ReturnType; - function rmTimeout() { - if (refreshTimeout) clearTimeout(refreshTimeout); - } - function restartRefreshTimer(evt: CustomEvent) { - rmTimeout(); - refreshTimeout = setTimeout( - refresh, - evt.detail.expires_in * 1000 - 60 * 1000, - ); - } - - const refresh = maybeRefresh.bind(globalThis, true); - - async function signOut() { - invariant(token, "not signed in"); - - const result = await processRevocationResponse( - await revocationRequest( - as, - client, - token.access_token, - oauthHttpOptions, - ), - ); - - rmTimeout(); - - // Clean up - removeLocal(); - token = undefined; - throwIfError(result); - eventTarget.dispatchTypedEvent("signOut", new Event("signOut")); - } - - let pendingSignIn: Promise | undefined; - async function signIn() { - if (pendingSignIn) { - return pendingSignIn; - } - try { - pendingSignIn = _signIn(); - return await pendingSignIn; - } finally { - pendingSignIn = undefined; - } - } /** Will throw if there is no token! */ async function _signIn() { // 1. Check if we have a refresh token in local storage - return token = await maybeRefresh() + return await maybeRefresh() // 2. If there is no refresh token we are likely trying to perform the callback ?? await maybeHandleAuthReturn() // 3. If we haven't been able to load the token from one of the two above ways, we need to make the initial auth request ?? await initiateLoginRedirect() as unknown as Token; } - eventTarget.addEventListener("signIn", restartRefreshTimer); - eventTarget.addEventListener("refresh", restartRefreshTimer); - - let token: Token | undefined; - const ret = Object.assign(async function ret() { - if (!token || Date.now() >= token.expires_at) { - token = await signIn(); - } - return token!.access_token; - }, { - signIn, - refresh, - signOut, - addEventListener: eventTarget.addEventListener.bind( - eventTarget, - ) as typeof eventTarget.addEventListener, - removeEventListener: eventTarget.removeEventListener.bind( - eventTarget, - ) as typeof eventTarget.removeEventListener, - }); - - return ret; + return getToken; } diff --git a/packages/oauth/src/index.ts b/packages/oauth/src/index.ts index 0cfab9691..dee6054fd 100644 --- a/packages/oauth/src/index.ts +++ b/packages/oauth/src/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ +export { createConfidentialOauthClient } from "./createConfidentialOauthClient.js"; export { createPublicOauthClient } from "./createPublicOauthClient.js"; export type { PublicOauthClient } from "./PublicOauthClient.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6344a97dc..32a3824a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,16 +79,16 @@ importers: version: 9.3.0 eslint-import-resolver-typescript: specifier: ^3.6.1 - version: 3.6.1(@typescript-eslint/parser@7.16.0)(eslint-plugin-import@2.29.1)(eslint@9.3.0) + version: 3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0) eslint-plugin-header: specifier: ^3.1.1 version: 3.1.1(eslint@9.3.0) eslint-plugin-import: specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) + version: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) eslint-plugin-unused-imports: specifier: ^3.2.0 - version: 3.2.0(eslint@9.3.0) + version: 3.2.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0) find-up-cli: specifier: ^6.0.0 version: 6.0.0 @@ -109,7 +109,7 @@ importers: version: 1.0.1(typescript@5.5.3) tsup: specifier: ^8.1.0 - version: 8.1.0(typescript@5.5.3) + version: 8.1.0(@microsoft/api-extractor@7.47.0(@types/node@20.14.10))(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3) turbo: specifier: ^2.0.4 version: 2.0.4 @@ -121,7 +121,7 @@ importers: version: 7.16.0(eslint@9.3.0)(typescript@5.5.3) vitest: specifier: ^1.6.0 - version: 1.6.0 + version: 1.6.0(@types/node@20.14.10) examples-extra/docs_example: dependencies: @@ -161,13 +161,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.4.5) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-react': specifier: ^4.2.1 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.39) @@ -185,10 +185,10 @@ importers: version: 8.4.39 rollup-plugin-visualizer: specifier: ^5.12.0 - version: 5.12.0 + version: 5.12.0(rollup@4.14.1) tailwindcss: specifier: ^3.4.4 - version: 3.4.4 + version: 3.4.4(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.4.5)) tslib: specifier: ^2.6.2 version: 2.6.2 @@ -197,7 +197,7 @@ importers: version: 5.4.5 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) examples/example-next-static-export: dependencies: @@ -206,7 +206,7 @@ importers: version: link:../../packages/e2e.generated.1.1.x next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1)(react@18.3.1) + version: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18 version: 18.3.1 @@ -246,7 +246,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@types/react': specifier: ^18 @@ -256,13 +256,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -277,7 +277,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) examples/example-tutorial-todo-aip-app: dependencies: @@ -292,7 +292,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) swr: specifier: ^2.2.5 version: 2.2.5(react@18.3.1) @@ -305,13 +305,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -326,7 +326,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) examples/example-tutorial-todo-app: dependencies: @@ -341,7 +341,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) swr: specifier: ^2.2.5 version: 2.2.5(react@18.3.1) @@ -354,13 +354,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -375,7 +375,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) examples/example-vue: dependencies: @@ -387,17 +387,17 @@ importers: version: 3.4.27(typescript@5.5.3) vue-router: specifier: ^4.2.5 - version: 4.3.2(vue@3.4.27) + version: 4.3.2(vue@3.4.27(typescript@5.5.3)) devDependencies: '@vitejs/plugin-vue': specifier: ^4.5.0 - version: 4.6.2(vite@5.3.4)(vue@3.4.27) + version: 4.6.2(vite@5.3.4(@types/node@20.14.10))(vue@3.4.27(typescript@5.5.3)) typescript: specifier: ^5.5.2 version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) vue-tsc: specifier: ^2 version: 2.0.26(typescript@5.5.3) @@ -657,10 +657,10 @@ importers: devDependencies: '@microsoft/api-documenter': specifier: ^7.25.3 - version: 7.25.3 + version: 7.25.3(@types/node@20.14.10) '@microsoft/api-extractor': specifier: ^7.47.0 - version: 7.47.0 + version: 7.47.0(@types/node@20.14.10) '@osdk/client.test.ontology': specifier: workspace:~ version: link:../client.test.ontology @@ -721,10 +721,10 @@ importers: devDependencies: '@microsoft/api-documenter': specifier: ^7.25.3 - version: 7.25.3 + version: 7.25.3(@types/node@20.14.10) '@microsoft/api-extractor': specifier: ^7.47.0 - version: 7.47.0 + version: 7.47.0(@types/node@20.14.10) '@osdk/internal.foundry': specifier: workspace:~ version: link:../internal.foundry @@ -912,7 +912,7 @@ importers: dependencies: next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1)(react@18.3.1) + version: 14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18 version: 18.3.1 @@ -961,7 +961,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@osdk/create-app.template-packager': specifier: workspace:~ @@ -983,13 +983,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -1004,7 +1004,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) packages/create-app.template.tutorial-todo-aip-app: dependencies: @@ -1016,7 +1016,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) swr: specifier: ^2.2.5 version: 2.2.5(react@18.3.1) @@ -1041,13 +1041,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -1062,7 +1062,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) packages/create-app.template.tutorial-todo-app: dependencies: @@ -1074,7 +1074,7 @@ importers: version: 18.3.1(react@18.3.1) react-router-dom: specifier: ^6.23.1 - version: 6.23.1(react-dom@18.3.1)(react@18.3.1) + version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) swr: specifier: ^2.2.5 version: 2.2.5(react@18.3.1) @@ -1099,13 +1099,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.0 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) eslint: specifier: ^8.57.0 version: 8.57.0 @@ -1120,7 +1120,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) packages/create-app.template.vue: dependencies: @@ -1129,7 +1129,7 @@ importers: version: 3.4.27(typescript@5.5.3) vue-router: specifier: ^4.2.5 - version: 4.3.2(vue@3.4.27) + version: 4.3.2(vue@3.4.27(typescript@5.5.3)) devDependencies: '@osdk/create-app.template-packager': specifier: workspace:~ @@ -1145,13 +1145,13 @@ importers: version: link:../monorepo.tsup '@vitejs/plugin-vue': specifier: ^4.5.0 - version: 4.6.2(vite@5.3.4)(vue@3.4.27) + version: 4.6.2(vite@5.3.4(@types/node@20.14.10))(vue@3.4.27(typescript@5.5.3)) typescript: specifier: ^5.5.2 version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) vue-tsc: specifier: ^2 version: 2.0.26(typescript@5.5.3) @@ -1282,6 +1282,25 @@ importers: specifier: ^5.5.2 version: 5.5.3 + packages/e2e.sandbox.oauth: + dependencies: + '@osdk/client': + specifier: workspace:~ + version: link:../client + '@osdk/oauth': + specifier: workspace:~ + version: link:../oauth + consola: + specifier: ^3.2.3 + version: 3.2.3 + tiny-invariant: + specifier: ^1.3.3 + version: 1.3.3 + devDependencies: + typescript: + specifier: ^5.5.2 + version: 5.5.3 + packages/e2e.sandbox.todoapp: dependencies: '@osdk/api': @@ -1329,13 +1348,13 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.16.0 - version: 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3) '@typescript-eslint/parser': specifier: ^7.16.0 - version: 7.16.0(eslint@8.57.0)(typescript@5.5.3) + version: 7.16.0(eslint@9.3.0)(typescript@5.5.3) '@vitejs/plugin-react': specifier: ^4.2.1 - version: 4.2.1(vite@5.3.4) + version: 4.2.1(vite@5.3.4(@types/node@20.14.10)) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.39) @@ -1344,10 +1363,10 @@ importers: version: 8.4.39 rollup-plugin-visualizer: specifier: ^5.12.0 - version: 5.12.0 + version: 5.12.0(rollup@4.14.1) tailwindcss: specifier: ^3.4.4 - version: 3.4.4 + version: 3.4.4(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) tslib: specifier: ^2.6.2 version: 2.6.2 @@ -1356,7 +1375,7 @@ importers: version: 5.5.3 vite: specifier: ^5.3.4 - version: 5.3.4(@types/node@20.12.12) + version: 5.3.4(@types/node@20.14.10) packages/e2e.test.foundry-sdk-generator: dependencies: @@ -1730,7 +1749,7 @@ importers: version: 5.5.2 vitest: specifier: ^1.6.0 - version: 1.6.0 + version: 1.6.0(@types/node@20.14.10) packages/internal.foundry: dependencies: @@ -2055,7 +2074,7 @@ importers: devDependencies: tsup: specifier: ^8.0.2 - version: 8.1.0(typescript@5.5.3) + version: 8.1.0(@microsoft/api-extractor@7.47.0(@types/node@20.14.10))(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3) packages/oauth: dependencies: @@ -2084,9 +2103,6 @@ importers: jest-extended: specifier: ^4.0.2 version: 4.0.2 - ts-expect: - specifier: ^1.3.0 - version: 1.3.0 typescript: specifier: ^5.5.2 version: 5.5.2 @@ -8331,35 +8347,35 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@microsoft/api-documenter@7.25.3': + '@microsoft/api-documenter@7.25.3(@types/node@20.14.10)': dependencies: - '@microsoft/api-extractor-model': 7.29.2 + '@microsoft/api-extractor-model': 7.29.2(@types/node@20.14.10) '@microsoft/tsdoc': 0.15.0 - '@rushstack/node-core-library': 5.4.1 - '@rushstack/terminal': 0.13.0 - '@rushstack/ts-command-line': 4.22.0 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.10) + '@rushstack/terminal': 0.13.0(@types/node@20.14.10) + '@rushstack/ts-command-line': 4.22.0(@types/node@20.14.10) js-yaml: 3.13.1 resolve: 1.22.8 transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor-model@7.29.2': + '@microsoft/api-extractor-model@7.29.2(@types/node@20.14.10)': dependencies: '@microsoft/tsdoc': 0.15.0 '@microsoft/tsdoc-config': 0.17.0 - '@rushstack/node-core-library': 5.4.1 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.10) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.47.0': + '@microsoft/api-extractor@7.47.0(@types/node@20.14.10)': dependencies: - '@microsoft/api-extractor-model': 7.29.2 + '@microsoft/api-extractor-model': 7.29.2(@types/node@20.14.10) '@microsoft/tsdoc': 0.15.0 '@microsoft/tsdoc-config': 0.17.0 - '@rushstack/node-core-library': 5.4.1 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.10) '@rushstack/rig-package': 0.5.2 - '@rushstack/terminal': 0.13.0 - '@rushstack/ts-command-line': 4.22.0 + '@rushstack/terminal': 0.13.0(@types/node@20.14.10) + '@rushstack/ts-command-line': 4.22.0(@types/node@20.14.10) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -8700,6 +8716,7 @@ snapshots: glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.30.10 + optionalDependencies: rollup: 3.29.1 '@rollup/plugin-inject@5.0.5(rollup@3.29.1)': @@ -8707,6 +8724,7 @@ snapshots: '@rollup/pluginutils': 5.1.0(rollup@3.29.1) estree-walker: 2.0.2 magic-string: 0.30.10 + optionalDependencies: rollup: 3.29.1 '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.1)': @@ -8717,6 +8735,7 @@ snapshots: is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 + optionalDependencies: rollup: 3.29.1 '@rollup/pluginutils@5.1.0(rollup@3.29.1)': @@ -8724,6 +8743,7 @@ snapshots: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 + optionalDependencies: rollup: 3.29.1 '@rollup/rollup-android-arm-eabi@4.14.1': @@ -8773,7 +8793,7 @@ snapshots: '@rushstack/eslint-patch@1.10.3': {} - '@rushstack/node-core-library@5.4.1': + '@rushstack/node-core-library@5.4.1(@types/node@20.14.10)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -8783,20 +8803,24 @@ snapshots: jju: 1.4.0 resolve: 1.22.8 semver: 7.5.4 + optionalDependencies: + '@types/node': 20.14.10 '@rushstack/rig-package@0.5.2': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.13.0': + '@rushstack/terminal@0.13.0(@types/node@20.14.10)': dependencies: - '@rushstack/node-core-library': 5.4.1 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.10) supports-color: 8.1.1 + optionalDependencies: + '@types/node': 20.14.10 - '@rushstack/ts-command-line@4.22.0': + '@rushstack/ts-command-line@4.22.0(@types/node@20.14.10)': dependencies: - '@rushstack/terminal': 0.13.0 + '@rushstack/terminal': 0.13.0(@types/node@20.14.10) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -8939,7 +8963,7 @@ snapshots: '@types/ws@8.5.10': dependencies: - '@types/node': 20.12.12 + '@types/node': 20.14.10 '@types/yargs-parser@21.0.2': {} @@ -8947,7 +8971,7 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.2 - '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.4.5) @@ -8960,11 +8984,12 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0)(eslint@8.57.0)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3) @@ -8977,11 +9002,12 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0)(eslint@9.3.0)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) @@ -8994,6 +9020,7 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9006,6 +9033,7 @@ snapshots: '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9018,6 +9046,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.16.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -9030,6 +9059,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.16.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9042,6 +9072,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.16.0 debug: 4.3.4 eslint: 9.3.0 + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9063,6 +9094,7 @@ snapshots: debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -9074,6 +9106,7 @@ snapshots: debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9085,6 +9118,7 @@ snapshots: debug: 4.3.4 eslint: 9.3.0 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9103,6 +9137,7 @@ snapshots: minimatch: 9.0.3 semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9117,6 +9152,7 @@ snapshots: minimatch: 9.0.4 semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -9131,6 +9167,7 @@ snapshots: minimatch: 9.0.4 semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -9180,20 +9217,20 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react@4.2.1(vite@5.3.4)': + '@vitejs/plugin-react@4.2.1(vite@5.3.4(@types/node@20.14.10))': dependencies: '@babel/core': 7.24.5 '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.24.5) '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.24.5) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.3.4(@types/node@20.12.12) + vite: 5.3.4(@types/node@20.14.10) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@4.6.2(vite@5.3.4)(vue@3.4.27)': + '@vitejs/plugin-vue@4.6.2(vite@5.3.4(@types/node@20.14.10))(vue@3.4.27(typescript@5.5.3))': dependencies: - vite: 5.3.4(@types/node@20.12.12) + vite: 5.3.4(@types/node@20.14.10) vue: 3.4.27(typescript@5.5.3) '@vitest/expect@1.6.0': @@ -9278,8 +9315,9 @@ snapshots: minimatch: 9.0.4 muggle-string: 0.4.1 path-browserify: 1.0.1 - typescript: 5.5.3 vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.5.3 '@vue/reactivity@3.4.27': dependencies: @@ -9296,7 +9334,7 @@ snapshots: '@vue/shared': 3.4.27 csstype: 3.1.3 - '@vue/server-renderer@3.4.27(vue@3.4.27)': + '@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.5.3))': dependencies: '@vue/compiler-ssr': 3.4.27 '@vue/shared': 3.4.27 @@ -9322,11 +9360,11 @@ snapshots: indent-string: 5.0.0 ajv-draft-04@1.0.0(ajv@8.13.0): - dependencies: + optionalDependencies: ajv: 8.13.0 ajv-formats@3.0.1(ajv@8.13.0): - dependencies: + optionalDependencies: ajv: 8.13.0 ajv@6.12.6: @@ -10209,11 +10247,12 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - eslint-import-resolver-webpack @@ -10227,13 +10266,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -10244,13 +10283,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0)(eslint-plugin-import@2.29.1)(eslint@9.3.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.1 eslint: 9.3.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@9.3.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -10261,33 +10300,46 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.3) debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.16.0)(eslint-plugin-import@2.29.1)(eslint@9.3.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@9.3.0): dependencies: - '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) eslint: 9.3.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.16.0)(eslint-plugin-import@2.29.1)(eslint@9.3.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@9.3.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) + eslint: 9.3.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0) transitivePeerDependencies: - supports-color @@ -10295,9 +10347,8 @@ snapshots: dependencies: eslint: 9.3.0 - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -10306,7 +10357,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -10316,14 +10367,15 @@ snapshots: object.values: 1.2.0 semver: 6.3.1 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0): dependencies: - '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -10332,7 +10384,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.3.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.3.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@9.3.0))(eslint@9.3.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -10342,6 +10394,8 @@ snapshots: object.values: 1.2.0 semver: 6.3.1 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -10397,10 +10451,12 @@ snapshots: semver: 6.3.1 string.prototype.matchall: 4.0.11 - eslint-plugin-unused-imports@3.2.0(eslint@9.3.0): + eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0): dependencies: eslint: 9.3.0 eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3) eslint-rule-composer@0.3.0: {} @@ -11511,8 +11567,9 @@ snapshots: path-to-regexp: 6.2.1 strict-event-emitter: 0.5.1 type-fest: 4.18.2 - typescript: 5.5.2 yargs: 17.7.2 + optionalDependencies: + typescript: 5.5.2 muggle-string@0.4.1: {} @@ -11530,7 +11587,7 @@ snapshots: neo-async@2.6.2: {} - next@14.2.3(@babel/core@7.24.5)(react-dom@18.3.1)(react@18.3.1): + next@14.2.3(@babel/core@7.24.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.3 '@swc/helpers': 0.5.5 @@ -11884,11 +11941,21 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.39 - postcss-load-config@4.0.1(postcss@8.4.39): + postcss-load-config@4.0.1(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.4.5)): dependencies: lilconfig: 2.1.0 + yaml: 2.4.2 + optionalDependencies: postcss: 8.4.39 + ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.4.5) + + postcss-load-config@4.0.1(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)): + dependencies: + lilconfig: 2.1.0 yaml: 2.4.2 + optionalDependencies: + postcss: 8.4.39 + ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3) postcss-nested@6.0.1(postcss@8.4.39): dependencies: @@ -11998,7 +12065,7 @@ snapshots: react-refresh@0.14.0: {} - react-router-dom@6.23.1(react-dom@18.3.1)(react@18.3.1): + react-router-dom@6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.16.1 react: 18.3.1 @@ -12190,12 +12257,14 @@ snapshots: '@rollup/plugin-inject': 5.0.5(rollup@3.29.1) rollup: 3.29.1 - rollup-plugin-visualizer@5.12.0: + rollup-plugin-visualizer@5.12.0(rollup@4.14.1): dependencies: open: 8.4.2 picomatch: 2.3.1 source-map: 0.7.4 yargs: 17.7.2 + optionalDependencies: + rollup: 4.14.1 rollup@3.29.1: optionalDependencies: @@ -12507,9 +12576,10 @@ snapshots: styled-jsx@5.1.1(@babel/core@7.24.5)(react@18.3.1): dependencies: - '@babel/core': 7.24.5 client-only: 0.0.1 react: 18.3.1 + optionalDependencies: + '@babel/core': 7.24.5 sucrase@3.34.0: dependencies: @@ -12546,7 +12616,34 @@ snapshots: react: 18.3.1 use-sync-external-store: 1.2.0(react@18.3.1) - tailwindcss@3.4.4: + tailwindcss@3.4.4(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.4.5)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.5.3 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.7 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.39 + postcss-import: 15.1.0(postcss@8.4.39) + postcss-js: 4.0.1(postcss@8.4.39) + postcss-load-config: 4.0.1(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.4.5)) + postcss-nested: 6.0.1(postcss@8.4.39) + postcss-selector-parser: 6.0.13 + resolve: 1.22.8 + sucrase: 3.34.0 + transitivePeerDependencies: + - ts-node + + tailwindcss@3.4.4(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -12565,7 +12662,7 @@ snapshots: postcss: 8.4.39 postcss-import: 15.1.0(postcss@8.4.39) postcss-js: 4.0.1(postcss@8.4.39) - postcss-load-config: 4.0.1(postcss@8.4.39) + postcss-load-config: 4.0.1(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) postcss-nested: 6.0.1(postcss@8.4.39) postcss-selector-parser: 6.0.13 resolve: 1.22.8 @@ -12650,6 +12747,25 @@ snapshots: '@ts-morph/common': 0.20.0 code-block-writer: 12.0.0 + ts-node@10.9.2(@types/node@20.14.10)(typescript@5.4.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.10 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.4.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.2): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -12668,6 +12784,25 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.10 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + tsc-absolute@1.0.1(typescript@5.5.3): dependencies: process-wrapper: 1.0.0 @@ -12682,7 +12817,7 @@ snapshots: tslib@2.6.2: {} - tsup@8.1.0(typescript@5.5.3): + tsup@8.1.0(@microsoft/api-extractor@7.47.0(@types/node@20.14.10))(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))(typescript@5.5.3): dependencies: bundle-require: 4.0.1(esbuild@0.21.5) cac: 6.7.14 @@ -12692,12 +12827,15 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.1(postcss@8.4.39) + postcss-load-config: 4.0.1(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) resolve-from: 5.0.0 rollup: 4.14.1 source-map: 0.8.0-beta.0 sucrase: 3.34.0 tree-kill: 1.2.2 + optionalDependencies: + '@microsoft/api-extractor': 7.47.0(@types/node@20.14.10) + postcss: 8.4.39 typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -12798,10 +12936,11 @@ snapshots: typescript-eslint@7.16.0(eslint@9.3.0)(typescript@5.5.3): dependencies: - '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0)(eslint@9.3.0)(typescript@5.5.3) + '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.3.0)(typescript@5.5.3))(eslint@9.3.0)(typescript@5.5.3) '@typescript-eslint/parser': 7.16.0(eslint@9.3.0)(typescript@5.5.3) '@typescript-eslint/utils': 7.16.0(eslint@9.3.0)(typescript@5.5.3) eslint: 9.3.0 + optionalDependencies: typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -12917,23 +13056,6 @@ snapshots: unist-util-stringify-position: 2.0.3 vfile-message: 2.0.4 - vite-node@1.6.0: - dependencies: - cac: 6.7.14 - debug: 4.3.4 - pathe: 1.1.1 - picocolors: 1.0.1 - vite: 5.3.4(@types/node@20.12.12) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - vite-node@1.6.0(@types/node@18.17.15): dependencies: cac: 6.7.14 @@ -12987,65 +13109,33 @@ snapshots: vite@5.3.4(@types/node@18.17.15): dependencies: - '@types/node': 18.17.15 esbuild: 0.21.5 postcss: 8.4.39 rollup: 4.14.1 optionalDependencies: + '@types/node': 18.17.15 fsevents: 2.3.3 vite@5.3.4(@types/node@20.12.12): dependencies: - '@types/node': 20.12.12 esbuild: 0.21.5 postcss: 8.4.39 rollup: 4.14.1 optionalDependencies: + '@types/node': 20.12.12 fsevents: 2.3.3 vite@5.3.4(@types/node@20.14.10): dependencies: - '@types/node': 20.14.10 esbuild: 0.21.5 postcss: 8.4.39 rollup: 4.14.1 optionalDependencies: + '@types/node': 20.14.10 fsevents: 2.3.3 - vitest@1.6.0: - dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.2 - chai: 4.3.10 - debug: 4.3.4 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.10 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.7.0 - strip-literal: 2.0.0 - tinybench: 2.5.1 - tinypool: 0.8.4 - vite: 5.3.4(@types/node@20.12.12) - vite-node: 1.6.0 - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - vitest@1.6.0(@types/node@18.17.15): dependencies: - '@types/node': 18.17.15 '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 '@vitest/snapshot': 1.6.0 @@ -13066,6 +13156,8 @@ snapshots: vite: 5.3.4(@types/node@18.17.15) vite-node: 1.6.0(@types/node@18.17.15) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 18.17.15 transitivePeerDependencies: - less - lightningcss @@ -13077,7 +13169,6 @@ snapshots: vitest@1.6.0(@types/node@20.12.12): dependencies: - '@types/node': 20.12.12 '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 '@vitest/snapshot': 1.6.0 @@ -13098,6 +13189,8 @@ snapshots: vite: 5.3.4(@types/node@20.12.12) vite-node: 1.6.0(@types/node@20.12.12) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.12.12 transitivePeerDependencies: - less - lightningcss @@ -13109,7 +13202,6 @@ snapshots: vitest@1.6.0(@types/node@20.14.10): dependencies: - '@types/node': 20.14.10 '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 '@vitest/snapshot': 1.6.0 @@ -13130,6 +13222,8 @@ snapshots: vite: 5.3.4(@types/node@20.14.10) vite-node: 1.6.0(@types/node@20.14.10) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.14.10 transitivePeerDependencies: - less - lightningcss @@ -13143,7 +13237,7 @@ snapshots: vscode-uri@3.0.8: {} - vue-router@4.3.2(vue@3.4.27): + vue-router@4.3.2(vue@3.4.27(typescript@5.5.3)): dependencies: '@vue/devtools-api': 6.6.1 vue: 3.4.27(typescript@5.5.3) @@ -13165,8 +13259,9 @@ snapshots: '@vue/compiler-dom': 3.4.27 '@vue/compiler-sfc': 3.4.27 '@vue/runtime-dom': 3.4.27 - '@vue/server-renderer': 3.4.27(vue@3.4.27) + '@vue/server-renderer': 3.4.27(vue@3.4.27(typescript@5.5.3)) '@vue/shared': 3.4.27 + optionalDependencies: typescript: 5.5.3 wcwidth@1.0.1: