diff --git a/.gitattributes b/.gitattributes index 9935da6dae7..6ce604795af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,10 @@ # Generated files - exclude from language stats and diffs client/dashboard/src/sdk/** linguist-generated +client/admin/src/sdk/** linguist-generated -whitespace server/gen/** linguist-generated server/internal/**/*.sql.go linguist-generated openrouter/** linguist-generated .speakeasy/*.lock linguist-generated .speakeasy/out.openapi.yaml linguist-generated +.speakeasy/out.admin.openapi.yaml linguist-generated **/descriptors.pb linguist-generated \ No newline at end of file diff --git a/.github/filters.yaml b/.github/filters.yaml index 329e2dbf702..667277327ae 100644 --- a/.github/filters.yaml +++ b/.github/filters.yaml @@ -44,16 +44,30 @@ tsframework: - "ts-framework/**" sdk: + - "client/admin/src/sdk/**" - "client/dashboard/src/sdk/**" - "package.json" - "pnpm-lock.yaml" sdk-gen: + - ".mise-tasks/gen/**" + - ".mise-tasks/test/gen-resolve.sh" + - ".mise-tasks/test/sdk-overlays.sh" + - ".speakeasy/out.admin.openapi.yaml" - ".speakeasy/workflow.yaml" + - "client/admin/src/sdk/**" - "client/dashboard/src/sdk/.speakeasy/gen.yaml" - "hooks/sdk/.speakeasy/gen.yaml" - "mise.toml" - "overlays/**" + - "server/design/**" + - "server/internal/constants/accounts.go" + - "server/internal/constants/auth.go" + - "server/internal/constants/spend_cap.go" + - "server/internal/constants/trials.go" + - "server/internal/conv/from.go" + - "server/internal/oops/codes.go" + - "server/internal/productfeatures/features.go" - "server/gen/http/openapi3.yaml" migrations: diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 084a55e30a8..33627d8480e 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1943,9 +1943,18 @@ jobs: - name: Install dependencies run: aube install --frozen-lockfile + - name: Test generated artifact conflict resolution + run: mise run test:gen-resolve + - name: Test SDK overlays run: mise run test:sdk-overlays + - name: Test SDK generation check + run: mise run test:gen-sdk + + - name: Check transformed SDK specs + run: mise run gen:sdk --check + - name: Regenerate SDK run: mise run gen:sdk diff --git a/.mise-tasks/gen/resolve.sh b/.mise-tasks/gen/resolve.sh index 67a09d25a20..2919783be7c 100755 --- a/.mise-tasks/gen/resolve.sh +++ b/.mise-tasks/gen/resolve.sh @@ -14,10 +14,24 @@ if ! git rev-parse --verify "$base" >/dev/null 2>&1; then exit 1 fi -paths=(.speakeasy client/dashboard/src/sdk server/gen) +paths=( + .speakeasy/openapi-hooks.yaml + .speakeasy/out.admin.openapi.yaml + .speakeasy/out.openapi.yaml + .speakeasy/workflow.lock + client/admin/src/sdk + client/dashboard/src/sdk + server/gen +) echo "==> Checking out $base for: ${paths[*]}" -git checkout "$base" -- "${paths[@]}" +for path in "${paths[@]}"; do + if git cat-file -e "$base:$path" 2>/dev/null; then + git checkout "$base" -- "$path" + else + echo "==> $path is absent from $base; keeping it for regeneration" + fi +done echo "==> Regenerating Goa server" mise run gen:goa-server diff --git a/.mise-tasks/gen/sdk.sh b/.mise-tasks/gen/sdk.sh index cb600deb2a0..31e561e6351 100755 --- a/.mise-tasks/gen/sdk.sh +++ b/.mise-tasks/gen/sdk.sh @@ -2,7 +2,7 @@ #MISE description="Generate SDK from OpenAPI spec" -#USAGE flag "-c --check" help="Check if the Gram-Internal OpenAPI output is up-to-date" +#USAGE flag "-c --check" help="Check if the Gram-Internal and Gram-Admin OpenAPI outputs are up-to-date" set -e @@ -23,18 +23,39 @@ generate() { check_inputs() { workflow=".speakeasy/workflow.yaml" - output=$(yq '.sources.Gram-Internal.output' "$workflow") - expected=$(mktemp) - cp "$output" "$expected" - trap 'cp "$expected" "$output"; rm -f "$expected"' EXIT - - generate --source Gram-Internal >/dev/null 2>&1 - - if ! diff -q "$expected" "$output" >/dev/null 2>&1; then - echo "Gram-Internal OpenAPI spec is out of date. Run 'mise gen:sdk' to regenerate." >&2 - exit 1 - fi - echo "Gram-Internal OpenAPI spec is up to date." + tmpdir=$(mktemp -d) + sources=(Gram-Internal Gram-Admin) + outputs=() + + for source in "${sources[@]}"; do + output=$(yq ".sources[\"${source}\"].output" "$workflow") + outputs+=("$output") + cp "$output" "$tmpdir/$source.yaml" + done + + restore_inputs() { + for i in "${!sources[@]}"; do + cp "$tmpdir/${sources[$i]}.yaml" "${outputs[$i]}" + done + rm -rf "$tmpdir" + } + trap restore_inputs EXIT + + status=0 + for i in "${!sources[@]}"; do + source=${sources[$i]} + output=${outputs[$i]} + generate --source "$source" >/dev/null 2>&1 + + if ! diff -q "$tmpdir/$source.yaml" "$output" >/dev/null 2>&1; then + echo "${source} OpenAPI spec is out of date. Run 'mise gen:sdk' to regenerate." >&2 + status=1 + else + echo "${source} OpenAPI spec is up to date." + fi + done + + return "$status" } if [[ "${usage_check:-}" == "true" ]]; then diff --git a/.mise-tasks/test/gen-resolve.sh b/.mise-tasks/test/gen-resolve.sh new file mode 100755 index 00000000000..c99b2767664 --- /dev/null +++ b/.mise-tasks/test/gen-resolve.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +#MISE description="Test generated artifact conflict resolution with a base missing a target" + +set -euo pipefail + +tmpdir=$(mktemp -d) +trap 'rm -rf "$tmpdir"' EXIT +repo="$tmpdir/repo" +mkdir -p "$repo" "$tmpdir/bin" +cp .mise-tasks/gen/resolve.sh "$repo/resolve.sh" + +cd "$repo" +git init -q -b main +git config user.email test@example.invalid +git config user.name "Resolve Test" +mkdir -p .speakeasy client/dashboard/src/sdk server/gen +cat >.speakeasy/workflow.yaml <<'EOF' +sources: + Gram-Internal: + output: .speakeasy/out.openapi.yaml +targets: + gram-internal: + output: client/dashboard/src/sdk +EOF +printf 'base\n' >.speakeasy/openapi-hooks.yaml +printf 'base\n' >.speakeasy/out.openapi.yaml +printf 'base\n' >.speakeasy/workflow.lock +printf 'base\n' >client/dashboard/src/sdk/marker +printf 'base\n' >server/gen/marker +git add . +git commit -qm base + +git switch -qc feature +cat >.speakeasy/workflow.yaml <<'EOF' +sources: + Gram-Internal: + output: .speakeasy/out.openapi.yaml + Gram-Admin: + output: .speakeasy/out.admin.openapi.yaml +targets: + gram-internal: + output: client/dashboard/src/sdk + gram-admin: + output: client/admin/src/sdk +EOF +printf 'feature\n' >.speakeasy/openapi-hooks.yaml +printf 'feature\n' >.speakeasy/out.openapi.yaml +printf 'feature\n' >.speakeasy/out.admin.openapi.yaml +printf 'feature\n' >.speakeasy/workflow.lock +printf 'feature\n' >client/dashboard/src/sdk/marker +printf 'feature\n' >server/gen/marker +mkdir -p client/admin/src/sdk +printf 'feature\n' >client/admin/src/sdk/marker +git add . +git commit -qm feature + +cat >"$tmpdir/bin/mise" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +case "$*" in + "run gen:goa-server") touch server/gen/goa-regenerated ;; + "run gen:sdk") + test "$(cat .speakeasy/openapi-hooks.yaml)" = base + test "$(cat .speakeasy/out.openapi.yaml)" = base + test "$(cat .speakeasy/out.admin.openapi.yaml)" = feature + test "$(cat .speakeasy/workflow.lock)" = base + test "$(cat client/admin/src/sdk/marker)" = feature + mkdir -p client/dashboard/src/sdk + touch client/dashboard/src/sdk/sdk-regenerated + admin_output=$(awk '/^ gram-admin:/{ target = 1; next } target && /output:/{ print $2; exit }' .speakeasy/workflow.yaml) + test "$admin_output" = client/admin/src/sdk + mkdir -p "$admin_output" + touch "$admin_output/sdk-regenerated" + ;; + *) echo "unexpected mise invocation: $*" >&2; exit 1 ;; +esac +EOF +chmod +x "$tmpdir/bin/mise" +PATH="$tmpdir/bin:$PATH" bash ./resolve.sh + +for marker in .speakeasy/openapi-hooks.yaml .speakeasy/out.openapi.yaml .speakeasy/workflow.lock client/dashboard/src/sdk/marker server/gen/marker; do + test "$(cat "$marker")" = base +done +grep -q '^ gram-admin:' .speakeasy/workflow.yaml +test -e server/gen/goa-regenerated +test -e client/dashboard/src/sdk/sdk-regenerated +test -e client/admin/src/sdk/sdk-regenerated +test "$(cat client/admin/src/sdk/marker)" = feature diff --git a/.mise-tasks/test/gen-sdk.sh b/.mise-tasks/test/gen-sdk.sh index a1a6c035193..09452da48ab 100755 --- a/.mise-tasks/test/gen-sdk.sh +++ b/.mise-tasks/test/gen-sdk.sh @@ -20,10 +20,21 @@ sources: transformations: - removeUnused: true output: internal-output.yaml + Gram-Admin: + inputs: + - location: admin.yaml + overlays: + - location: admin-overlay.yaml + transformations: + - removeUnused: true + output: admin-output.yaml EOF printf 'internal\n' >internal.yaml +printf 'admin\n' >admin.yaml printf 'overlay\n' >internal-overlay.yaml +printf 'overlay\n' >admin-overlay.yaml printf 'internal\n' >internal-output.yaml +printf 'admin\n' >admin-output.yaml cat >"$tmpdir/bin/speakeasy" <<'EOF' #!/usr/bin/env bash @@ -39,8 +50,11 @@ if [[ "$1" == "run" ]]; then fi shift done - test "$source" = Gram-Internal - cp internal.yaml internal-output.yaml + case "$source" in + Gram-Internal) cp internal.yaml internal-output.yaml ;; + Gram-Admin) cp admin.yaml admin-output.yaml ;; + *) exit 1 ;; + esac exit fi @@ -52,7 +66,9 @@ chmod +x "$tmpdir/bin/speakeasy" export SPEAKEASY_LOG="$tmpdir/speakeasy.log" PATH="$tmpdir/bin:$PATH" usage_check=true bash ./sdk.sh grep -q '^run .*--source Gram-Internal' "$SPEAKEASY_LOG" +grep -q '^run .*--source Gram-Admin' "$SPEAKEASY_LOG" test "$(cat internal-output.yaml)" = internal +test "$(cat admin-output.yaml)" = admin printf 'changed\n' >internal.yaml if PATH="$tmpdir/bin:$PATH" usage_check=true bash ./sdk.sh >/dev/null 2>&1; then diff --git a/.mise-tasks/test/sdk-overlays.sh b/.mise-tasks/test/sdk-overlays.sh index 5369e1576ec..35554c4bc50 100755 --- a/.mise-tasks/test/sdk-overlays.sh +++ b/.mise-tasks/test/sdk-overlays.sh @@ -1,12 +1,13 @@ #!/usr/bin/env bash -#MISE description="Prove Admin operations cannot affect the Dashboard SDK input" +#MISE description="Prove SDK overlays isolate and name Admin operations" set -euo pipefail raw_spec="server/gen/http/openapi3.yaml" common_overlay="overlays/goa-common.yaml" dashboard_overlay="overlays/dashboard-sdk.yaml" +admin_overlay="overlays/admin-sdk.yaml" tmpdir=$(mktemp -d) trap 'rm -rf "$tmpdir"' EXIT @@ -59,3 +60,31 @@ if grep -q 'admin_auth_header_Authorization' "$output"; then echo "Dashboard input contains Admin auth" >&2 exit 1 fi + +speakeasy overlay apply \ + --schema "$tmpdir/baseline.common.yaml" \ + --overlay "$admin_overlay" \ + --out "$tmpdir/admin.yaml" >/dev/null 2>&1 + +operation_rows=$( + yq -o=json "$tmpdir/admin.yaml" | + jq -r '.paths[][] | select(.operationId and (."x-speakeasy-ignore" != true)) | [.operationId, (."x-speakeasy-name-override" // "")] | @tsv' +) +if [ -z "$operation_rows" ]; then + echo "Expected active Admin operations, found none" >&2 + exit 1 +fi + +while IFS=$'\t' read -r operation_id sdk_name; do + if [[ $operation_id != admin* ]]; then + echo "Expected stable admin-prefixed operation ID, found $operation_id" >&2 + exit 1 + fi + local_name=${operation_id#admin} + first_letter=$(printf '%s' "${local_name:0:1}" | tr '[:upper:]' '[:lower:]') + expected_name="$first_letter${local_name:1}" + if [ "$sdk_name" != "$expected_name" ]; then + echo "Expected $operation_id to have SDK name $expected_name, found ${sdk_name:-none}" >&2 + exit 1 + fi +done <<<"$operation_rows" diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 59ed30842e8..312d7bfb495 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -7,6 +7,7 @@ "**/*.mdx", "/.speakeasy/**", "/client/admin/src/routeTree.gen.ts", + "/client/admin/src/sdk/**", "/client/dashboard/index.html", "/client/dashboard/public/external/**", "/client/dashboard/src/App.css", diff --git a/.speakeasy/out.admin.openapi.yaml b/.speakeasy/out.admin.openapi.yaml new file mode 100644 index 00000000000..11a1833e2e7 --- /dev/null +++ b/.speakeasy/out.admin.openapi.yaml @@ -0,0 +1,3489 @@ +openapi: 3.0.3 +info: + title: Gram API Description + description: Gram is the tools platform for AI agents + version: 0.0.1 +servers: + - url: / +paths: + /admin/auth.callback: + get: + tags: + - admin + summary: callback admin + operationId: admin#callback + parameters: + - name: code + in: query + description: The authorization code returned by the provider on success + allowEmptyValue: true + schema: + type: string + description: The authorization code returned by the provider on success + - name: state + in: query + description: The state parameter returned, which should match the one generated in the login step + allowEmptyValue: true + required: true + schema: + type: string + description: The state parameter returned, which should match the one generated in the login step + - name: error + in: query + description: OAuth error code returned by the provider (e.g. login_required for prompt=none failures) + allowEmptyValue: true + schema: + type: string + description: OAuth error code returned by the provider (e.g. login_required for prompt=none failures) + - name: error_description + in: query + description: Human-readable OAuth error description + allowEmptyValue: true + schema: + type: string + description: Human-readable OAuth error description + - name: gram_admin_login_state + in: cookie + description: The state cookie value for CSRF sanity checking against the state parameter + allowEmptyValue: true + schema: + type: string + description: The state cookie value for CSRF sanity checking against the state parameter + responses: + "307": + description: Temporary Redirect response. + headers: + Location: + description: The URL to redirect the client to after processing the callback + schema: + type: string + description: The URL to redirect the client to after processing the callback + Set-Cookie: + description: Admin session cookie + schema: + type: string + description: Admin session cookie + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-ignore: true + /admin/auth.login: + get: + tags: + - admin + summary: login admin + operationId: admin#login + parameters: + - name: return_to + in: query + description: Optional URL to return the user to after login. Relative paths and absolute URLs whose origin is in the admin allowed-origins list are accepted. + allowEmptyValue: true + schema: + type: string + description: Optional URL to return the user to after login. Relative paths and absolute URLs whose origin is in the admin allowed-origins list are accepted. + - name: prompt + in: query + description: Optional OAuth prompt parameter forwarded to the provider. Pass 'none' to attempt silent re-authentication. + allowEmptyValue: true + schema: + type: string + description: Optional OAuth prompt parameter forwarded to the provider. Pass 'none' to attempt silent re-authentication. + responses: + "307": + description: Temporary Redirect response. + headers: + Location: + description: The URL to redirect the user to for Google authentication + schema: + type: string + description: The URL to redirect the user to for Google authentication + Set-Cookie: + description: CSRF state cookie for sanity-checking the callback + schema: + type: string + description: CSRF state cookie for sanity-checking the callback + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-ignore: true + /admin/auth.logout: + post: + tags: + - admin + summary: logout admin + operationId: adminLogout + parameters: [] + responses: + "204": + description: No Content response. + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: logout + /admin/organization.activity: + get: + description: Lists activity belonging to an organization for admin operators. + operationId: adminListOrganizationActivity + parameters: + - allowEmptyValue: true + description: Organization ID. + in: query + name: organization_id + required: true + schema: + description: Organization ID. + type: string + - allowEmptyValue: true + description: Cursor for paginating through organization activity. + in: query + name: cursor + schema: + description: Cursor for paginating through organization activity. + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/AdminListOrganizationActivityResult' + description: OK response. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'bad_request: request is invalid' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unauthorized: unauthorized access' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'forbidden: permission denied' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'not_found: resource not found' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'conflict: resource already exists' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unsupported_media: unsupported media type' + "422": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'invalid: request contains one or more invalidation fields' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unexpected: an unexpected error occurred' + "502": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'gateway_error: an unexpected error occurred' + summary: listOrganizationActivity admin + tags: + - admin + x-speakeasy-pagination: + inputs: + - in: parameters + name: cursor + type: cursor + outputs: + nextCursor: $.next_cursor + type: cursor + x-speakeasy-name-override: listOrganizationActivity + /admin/organization.cancelStripeSubscription: + post: + tags: + - admin + summary: cancelStripeSubscription admin + description: Schedules an organization's PAYG subscription to cancel at period end. + operationId: adminCancelStripeSubscription + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CancelStripeSubscriptionRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminStripeSubscription' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "503": + description: 'unavailable: service temporarily unavailable' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: cancelStripeSubscription + /admin/organization.chatAnalysisSettings: + get: + tags: + - admin + summary: getOrganizationChatAnalysisSettings admin + operationId: adminGetOrganizationChatAnalysisSettings + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminChatAnalysisSettings' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getOrganizationChatAnalysisSettings + post: + tags: + - admin + summary: setOrganizationChatAnalysisSettings admin + operationId: adminSetOrganizationChatAnalysisSettings + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SetOrganizationChatAnalysisSettingsRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminChatAnalysisSettings' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: setOrganizationChatAnalysisSettings + /admin/organization.chatAnalysisTrigger: + post: + tags: + - admin + summary: triggerOrganizationChatAnalysis admin + operationId: adminTriggerOrganizationChatAnalysis + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TriggerOrganizationChatAnalysisRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminChatAnalysisTriggerResult' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: triggerOrganizationChatAnalysis + /admin/organization.create: + post: + tags: + - admin + summary: createOrganization admin + description: 'Creates an organization in WorkOS and in Gram, so an operator does not have to leave the admin app for the WorkOS dashboard. The organization starts with no members, is not whitelisted, and gets no trial. Idempotent against the WorkOS organization webhook: the Gram ID is derived from the WorkOS ID, so both writers converge on one row.' + operationId: adminCreateOrganization + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateOrganizationRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: createOrganization + /admin/organization.disable: + post: + tags: + - admin + summary: disableOrganization admin + description: 'Disables an organization, recording the moment of the action in disabled_at. Idempotent: disabling an already-disabled organization keeps the original timestamp.' + operationId: adminDisableOrganization + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DisableOrganizationRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: disableOrganization + /admin/organization.enable: + post: + tags: + - admin + summary: enableOrganization admin + description: 'Re-enables a disabled organization by clearing disabled_at. Idempotent: an organization that is already active is unaffected.' + operationId: adminEnableOrganization + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EnableOrganizationRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: enableOrganization + /admin/organization.features: + get: + operationId: adminGetOrganizationFeatures + parameters: + - allowEmptyValue: true + in: query + name: organization_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ProductFeatures' + description: OK response. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'bad_request: request is invalid' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unauthorized: unauthorized access' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'forbidden: permission denied' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'not_found: resource not found' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'conflict: resource already exists' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unsupported_media: unsupported media type' + "422": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'invalid: request contains one or more invalidation fields' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unexpected: an unexpected error occurred' + "502": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'gateway_error: an unexpected error occurred' + summary: getOrganizationFeatures admin + tags: + - admin + x-speakeasy-react-hook: + name: AdminOrganizationFeatures + x-speakeasy-name-override: getOrganizationFeatures + post: + operationId: adminSetOrganizationFeature + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SetOrganizationFeatureRequestBody' + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ProductFeatures' + description: OK response. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'bad_request: request is invalid' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unauthorized: unauthorized access' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'forbidden: permission denied' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'not_found: resource not found' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'conflict: resource already exists' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unsupported_media: unsupported media type' + "422": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'invalid: request contains one or more invalidation fields' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unexpected: an unexpected error occurred' + "502": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'gateway_error: an unexpected error occurred' + summary: setOrganizationFeature admin + tags: + - admin + x-speakeasy-react-hook: + name: SetAdminOrganizationFeature + x-speakeasy-name-override: setOrganizationFeature + /admin/organization.get: + get: + tags: + - admin + summary: getOrganization admin + description: Returns full admin details for a single organization by id or slug. + operationId: adminGetOrganization + parameters: + - name: id_or_slug + in: query + description: Organization ID or slug. + allowEmptyValue: true + required: true + schema: + type: string + description: Organization ID or slug. + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getOrganization + /admin/organization.inferenceKeys: + get: + tags: + - admin + summary: getInferenceKeys admin + description: Returns the configured state of every materialized platform-managed OpenRouter key for an organization. + operationId: adminGetInferenceKeys + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "200": + description: OK response. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AdminInferenceKey' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getInferenceKeys + /admin/organization.inferenceSpendHistory: + get: + tags: + - admin + summary: getInferenceSpendHistory admin + description: Returns up to twelve complete UTC calendar months of recorded inference spend for an organization. + operationId: adminGetInferenceSpendHistory + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "200": + description: OK response. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AdminInferenceSpendMonth' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getInferenceSpendHistory + /admin/organization.members: + get: + tags: + - admin + summary: listOrganizationMembers admin + description: Lists members of an organization (admin view, no auth scoping). + operationId: adminListOrganizationMembers + parameters: + - name: organization_id + in: query + description: Organization ID. + allowEmptyValue: true + required: true + schema: + type: string + description: Organization ID. + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminListOrganizationMembersResult' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: listOrganizationMembers + /admin/organization.open-dashboard: + post: + tags: + - admin + summary: openOrganizationInDashboard admin + operationId: adminOpenOrganizationInDashboard + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "303": + description: See Other response. + headers: + Cache-Control: + schema: + type: string + Location: + schema: + type: string + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-ignore: true + /admin/organization.paygBillingSummary: + get: + tags: + - admin + summary: getPaygBillingSummary admin + description: Returns current PAYG usage and estimated cost for an organization. + operationId: adminGetPaygBillingSummary + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminPaygBillingSummary' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "503": + description: 'unavailable: service temporarily unavailable' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getPaygBillingSummary + /admin/organization.projects: + get: + tags: + - admin + summary: listOrganizationProjects admin + description: Lists projects belonging to an organization (admin view, no auth scoping). + operationId: adminListOrganizationProjects + parameters: + - name: organization_id + in: query + description: Organization ID. + allowEmptyValue: true + required: true + schema: + type: string + description: Organization ID. + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminListOrganizationProjectsResult' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: listOrganizationProjects + /admin/organization.resumeStripeSubscription: + post: + tags: + - admin + summary: resumeStripeSubscription admin + description: Removes a scheduled period-end cancellation from an organization's PAYG subscription. + operationId: adminResumeStripeSubscription + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResumeStripeSubscriptionRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminStripeSubscription' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "503": + description: 'unavailable: service temporarily unavailable' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: resumeStripeSubscription + /admin/organization.setInferenceKeyMonthlyLimit: + post: + tags: + - admin + summary: setInferenceKeyMonthlyLimit admin + description: Sets the monthly limit for one materialized platform-managed OpenRouter key. + operationId: adminSetInferenceKeyMonthlyLimit + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SetInferenceKeyMonthlyLimitRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminInferenceKeyLimit' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: setInferenceKeyMonthlyLimit + /admin/organization.stripeSubscription: + get: + tags: + - admin + summary: getStripeSubscription admin + description: Returns the live Stripe subscription and payment state for an organization. + operationId: adminGetStripeSubscription + parameters: + - name: organization_id + in: query + allowEmptyValue: true + required: true + schema: + type: string + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminStripeSubscription' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "503": + description: 'unavailable: service temporarily unavailable' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getStripeSubscription + /admin/organization.update: + post: + tags: + - admin + summary: updateOrganization admin + description: Updates admin-managed fields on an organization. At least one of account_type or whitelisted must be supplied. + operationId: adminUpdateOrganization + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrganizationRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: updateOrganization + /admin/organizations.bulkUpdateAccountType: + post: + tags: + - admin + summary: bulkUpdateAccountType admin + description: Sets one account type on many organizations in a single statement. An ID that matches no organization is reported back rather than failing the batch, so a stale ID costs the operator that row and not the whole call. + operationId: adminBulkUpdateAccountType + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BulkUpdateAccountTypeRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminBulkUpdateAccountTypeResult' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: bulkUpdateAccountType + /admin/organizations.list: + get: + description: Lists organizations for admin operations with optional search and filters. + operationId: adminListOrganizations + parameters: + - allowEmptyValue: true + description: Search term, trimmed of surrounding whitespace. Matches name and slug as a case-insensitive substring, with % and _ taken literally, and matches organization id and WorkOS id exactly, ignoring case. An id match also returns an organization that disabled_states or include_disabled would otherwise hide; it still respects account_type, account_types, trial_states and cursor. + in: query + name: q + schema: + description: Search term, trimmed of surrounding whitespace. Matches name and slug as a case-insensitive substring, with % and _ taken literally, and matches organization id and WorkOS id exactly, ignoring case. An id match also returns an organization that disabled_states or include_disabled would otherwise hide; it still respects account_type, account_types, trial_states and cursor. + type: string + - allowEmptyValue: true + description: Filter by a single gram_account_type (e.g. free, pro, payg, enterprise). Superseded by account_types, which it joins as one more member of the same set. + in: query + name: account_type + schema: + description: Filter by a single gram_account_type (e.g. free, pro, payg, enterprise). Superseded by account_types, which it joins as one more member of the same set. + type: string + - allowEmptyValue: true + description: Match any of these gram_account_type values. Empty matches every account type. A value no organization carries matches nothing rather than failing the request. + in: query + name: account_types + schema: + description: Match any of these gram_account_type values. Empty matches every account type. A value no organization carries matches nothing rather than failing the request. + items: + type: string + type: array + - allowEmptyValue: true + description: Match any of running, ending_soon, expired, demoted, converted or none. Empty matches every trial state. An unrecognised value matches nothing rather than failing the request. + in: query + name: trial_states + schema: + description: Match any of running, ending_soon, expired, demoted, converted or none. Empty matches every trial state. An unrecognised value matches nothing rather than failing the request. + items: + type: string + type: array + - allowEmptyValue: true + description: Match any of active or disabled. Empty falls back to include_disabled. An unrecognised value matches nothing rather than failing the request. + in: query + name: disabled_states + schema: + description: Match any of active or disabled. Empty falls back to include_disabled. An unrecognised value matches nothing rather than failing the request. + items: + type: string + type: array + - allowEmptyValue: true + description: Include organizations with disabled_at set. Defaults to false. Superseded by disabled_states, which overrides it outright when supplied. + in: query + name: include_disabled + schema: + description: Include organizations with disabled_at set. Defaults to false. Superseded by disabled_states, which overrides it outright when supplied. + type: boolean + - allowEmptyValue: true + description: 'Pagination cursor: id of the last item from the previous page. Ignored when sort or page is supplied.' + in: query + name: cursor + schema: + description: 'Pagination cursor: id of the last item from the previous page. Ignored when sort or page is supplied.' + type: string + - allowEmptyValue: true + description: Page size (default 50, max 100). + in: query + name: limit + schema: + description: Page size (default 50, max 100). + format: int64 + type: integer + - allowEmptyValue: true + description: 'Column to sort by: name, slug, account_type, member_count, created_at, disabled_at or trial_ends_at. Any other value sorts by id. Supplying it selects offset paging.' + in: query + name: sort + schema: + description: 'Column to sort by: name, slug, account_type, member_count, created_at, disabled_at or trial_ends_at. Any other value sorts by id. Supplying it selects offset paging.' + type: string + - allowEmptyValue: true + description: 'Sort direction, asc or desc, applied to the column named by sort. Any other value sorts ascending. On its own it does nothing: without sort there is no column to reverse, so it neither reorders the results nor selects offset paging.' + in: query + name: direction + schema: + description: 'Sort direction, asc or desc, applied to the column named by sort. Any other value sorts ascending. On its own it does nothing: without sort there is no column to reverse, so it neither reorders the results nor selects offset paging.' + type: string + - allowEmptyValue: true + description: 1-based page number for offset paging (default 1). Supplying it selects offset paging. + in: query + name: page + schema: + description: 1-based page number for offset paging (default 1). Supplying it selects offset paging. + format: int64 + type: integer + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/AdminListOrganizationsResult' + description: OK response. + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'bad_request: request is invalid' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unauthorized: unauthorized access' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'forbidden: permission denied' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'not_found: resource not found' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'conflict: resource already exists' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unsupported_media: unsupported media type' + "422": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'invalid: request contains one or more invalidation fields' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'unexpected: an unexpected error occurred' + "502": + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: 'gateway_error: an unexpected error occurred' + summary: listOrganizations admin + tags: + - admin + x-speakeasy-pagination: + inputs: + - in: parameters + name: cursor + type: cursor + outputs: + nextCursor: $.next_cursor + type: cursor + x-speakeasy-name-override: listOrganizations + /admin/organizations.stats: + get: + tags: + - admin + summary: getOrganizationStats admin + description: 'Returns platform-wide organization counts for the strip above the organizations list. Every figure counts the whole platform: none of them narrows to the caller''s list filters, so the strip does not move when an operator filters.' + operationId: adminGetOrganizationStats + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganizationStats' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getOrganizationStats + /admin/project.get: + get: + tags: + - admin + summary: getProject admin + description: Returns full admin details for a project by id or slug, including aggregated counts of child resources. + operationId: adminGetProject + parameters: + - name: id_or_slug + in: query + description: Project ID or slug. + allowEmptyValue: true + required: true + schema: + type: string + description: Project ID or slug. + - name: organization_id_or_slug + in: query + description: Organization the project must belong to, by id or slug. A project outside it is reported as not found. Optional, because the global project lookup has no organization to scope by. + allowEmptyValue: true + schema: + type: string + description: Organization the project must belong to, by id or slug. A project outside it is reported as not found. Optional, because the global project lookup has no organization to scope by. + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminProjectDetail' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getProject + /admin/session.get: + get: + tags: + - admin + summary: getSession admin + operationId: adminGetSession + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminSession' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: getSession + /admin/trial.convert: + post: + tags: + - admin + summary: markEnterpriseTrialConverted admin + description: Records that an organization's enterprise trial converted to a signed contract. + operationId: adminMarkEnterpriseTrialConverted + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MarkEnterpriseTrialConvertedRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/MarkEnterpriseTrialConvertedResult' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: markEnterpriseTrialConverted + /admin/trial.extend: + post: + tags: + - admin + summary: extendTrial admin + description: 'Extends a running enterprise trial by adding days to its current end date. Only a running trial can be extended: one that has converted, has been demoted, or has already expired is rejected rather than re-armed.' + operationId: adminExtendTrial + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExtendTrialRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: extendTrial + /admin/trial.rearm: + post: + tags: + - admin + summary: rearmTrial admin + description: 'Puts a demoted enterprise trial back on: restores the organization''s account type and whitelist flag, revives its model provider keys, and gives the trial a fresh run of the given length counted from now. Only a demoted trial can be re-armed; one that has converted or is already running is rejected.' + operationId: adminRearmTrial + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RearmTrialRequestBody' + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/AdminOrganization' + "400": + description: 'bad_request: request is invalid' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "401": + description: 'unauthorized: unauthorized access' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "403": + description: 'forbidden: permission denied' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "404": + description: 'not_found: resource not found' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "409": + description: 'conflict: resource already exists' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "415": + description: 'unsupported_media: unsupported media type' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "422": + description: 'invalid: request contains one or more invalidation fields' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "500": + description: 'unexpected: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + "502": + description: 'gateway_error: an unexpected error occurred' + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + x-speakeasy-name-override: rearmTrial +components: + schemas: + AdminBulkUpdateAccountTypeResult: + type: object + properties: + missing_ids: + type: array + items: + type: string + description: IDs from the request that matched no organization, deduplicated and in request order. Nothing was written for these. + updated_ids: + type: array + items: + type: string + description: 'IDs of the organizations whose account type was set. Order is unspecified: do not rely on it.' + description: Outcome of a bulk account type change. + required: + - updated_ids + - missing_ids + AdminChatAnalysisSettings: + type: object + properties: + business_memory_daily_cap: + type: integer + format: int64 + business_memory_enabled: + type: boolean + is_default: + type: boolean + organization_id: + type: string + work_units_daily_cap: + type: integer + format: int64 + work_units_enabled: + type: boolean + required: + - organization_id + - work_units_enabled + - work_units_daily_cap + - business_memory_enabled + - business_memory_daily_cap + - is_default + AdminChatAnalysisTriggerResult: + type: object + properties: + projects_signaled: + type: integer + format: int64 + required: + - projects_signaled + AdminInferenceKey: + type: object + properties: + credits_used: + type: number + description: Credits spent this month in USD. + format: double + disable_causes: + type: array + items: + type: string + description: Active internal disable causes. Omitted for legacy unclassified rows. + disable_causes_classified: + type: boolean + description: Whether disable_causes is classified, including an explicitly empty cause set. + disabled: + type: boolean + key_type: + type: string + monthly_credits: + type: integer + format: int64 + description: Current usage and configured state for one materialized platform-managed OpenRouter key, without key material or provider identifiers. + required: + - key_type + - credits_used + - monthly_credits + - disabled + - disable_causes_classified + AdminInferenceKeyLimit: + type: object + properties: + key_type: + type: string + monthly_credits: + type: integer + format: int64 + description: The configured monthly limit for one materialized platform-managed OpenRouter key. + required: + - key_type + - monthly_credits + AdminInferenceSpendMonth: + type: object + properties: + period_end: + type: string + description: Exclusive end of the UTC calendar month. + format: date + period_start: + type: string + format: date + spend_usd: + type: string + required: + - period_start + - period_end + - spend_usd + AdminListOrganizationActivityResult: + type: object + properties: + logs: + type: array + items: + $ref: '#/components/schemas/AuditLog' + description: List of organization activity. + next_cursor: + type: string + description: Cursor for the next page of results. + required: + - logs + AdminListOrganizationMembersResult: + type: object + properties: + members: + type: array + items: + $ref: '#/components/schemas/AdminOrganizationMember' + description: The members of the organization. + required: + - members + AdminListOrganizationProjectsResult: + type: object + properties: + projects: + type: array + items: + $ref: '#/components/schemas/AdminProject' + description: The projects belonging to the organization. + required: + - projects + AdminListOrganizationsResult: + type: object + properties: + next_cursor: + type: string + description: Cursor for the next page; empty when exhausted. Omitted in offset mode. + organizations: + type: array + items: + $ref: '#/components/schemas/AdminOrganization' + description: The page of organizations. + total: + type: integer + description: Number of organizations matching the filters, before paging. + format: int64 + required: + - organizations + - total + AdminOrganization: + type: object + properties: + account_type: + type: string + description: Gram account type (e.g. free, pro, payg, enterprise). + created_at: + type: string + description: The creation date of the organization. + format: date-time + disabled_at: + type: string + description: The time at which the organization was disabled, if any. + format: date-time + id: + type: string + description: The ID of the organization + member_count: + type: integer + description: Number of active members in the organization. + format: int64 + name: + type: string + description: The name of the organization + slug: + type: string + description: The slug of the organization + trial_converted_at: + type: string + description: The time at which the trial converted to a paid plan, if any. + format: date-time + trial_demoted_at: + type: string + description: The time at which the organization was demoted after its trial, if any. + format: date-time + trial_ends_at: + type: string + description: The time at which the enterprise trial ends. Absent when the organization never trialled. + format: date-time + trial_state: + type: string + description: Lifecycle state of the organization's enterprise trial. + enum: + - none + - running + - ending_soon + - expired + - demoted + - converted + trial_tier: + type: string + description: The trial tier. Absent when the organization never trialled. + updated_at: + type: string + description: The last update date of the organization. + format: date-time + whitelisted: + type: boolean + description: Whether the organization is whitelisted for full access. + workos_id: + type: string + description: WorkOS organization ID, if linked. + description: Organization details surfaced to admin operators. + required: + - id + - name + - slug + - account_type + - whitelisted + - member_count + - created_at + - updated_at + AdminOrganizationMember: + type: object + properties: + created_at: + type: string + format: date-time + display_name: + type: string + description: User display name. + email: + type: string + description: User email address. + id: + type: string + description: User ID. + last_login: + type: string + description: The time the user last logged in, if any. + format: date-time + updated_at: + type: string + format: date-time + description: Organization member surfaced to admin operators. + required: + - id + - email + - display_name + - created_at + - updated_at + AdminOrganizationStats: + type: object + properties: + created_last_7_days: + type: integer + description: Organizations created in the last 7 days, whatever their current status. + format: int64 + customers: + type: integer + description: Organizations on a paid account type (payg or enterprise), disabled ones included. + format: int64 + customers_created_last_7_days: + type: integer + description: Customers created in the last 7 days, whatever their current status. + format: int64 + disabled: + type: integer + description: Organizations with disabled_at set. + format: int64 + disabled_last_7_days: + type: integer + description: Organizations disabled in the last 7 days. + format: int64 + total: + type: integer + description: Every organization on the platform, disabled ones included. + format: int64 + trials_ending_soon: + type: integer + description: Organizations whose trial_state is ending_soon. + format: int64 + description: Platform-wide organization counts surfaced above the admin organizations list. + required: + - total + - created_last_7_days + - customers + - customers_created_last_7_days + - trials_ending_soon + - disabled + - disabled_last_7_days + AdminPaygBillingSummary: + type: object + properties: + estimated_total_usd: + type: string + other_inference_spend_usd: + type: string + period_end: + type: string + format: date-time + period_start: + type: string + format: date-time + recorded_through: + type: string + format: date + tum_cost_usd: + type: string + tum_tokens: + type: integer + format: int64 + tum_unit_price_usd: + type: string + required: + - period_start + - period_end + - tum_tokens + - tum_unit_price_usd + - tum_cost_usd + - other_inference_spend_usd + - estimated_total_usd + AdminProject: + type: object + properties: + created_at: + type: string + description: The creation date of the project. + format: date-time + id: + type: string + description: The ID of the project + mcp_server_count: + type: integer + description: Number of MCP servers in the project, counting both toolset-backed servers and mcp_servers rows. + format: int64 + name: + type: string + description: The name of the project + slug: + type: string + description: The slug of the project + updated_at: + type: string + description: The last update date of the project. + format: date-time + description: Project summary surfaced to admin operators. + required: + - id + - name + - slug + - mcp_server_count + - created_at + - updated_at + AdminProjectDetail: + type: object + properties: + api_key_count: + type: integer + description: Number of active API keys in the project. + format: int64 + assistant_count: + type: integer + description: Number of active assistants in the project. + format: int64 + created_at: + type: string + format: date-time + deployment_count: + type: integer + description: Total number of deployments in the project. + format: int64 + environment_count: + type: integer + description: Number of active environments in the project. + format: int64 + functions_runner_version: + type: string + description: Functions runner version pin, if set. + http_tool_count: + type: integer + description: Number of active HTTP tool definitions in the project. + format: int64 + id: + type: string + description: Project ID. + logo_asset_id: + type: string + description: Project logo asset ID, if set. + name: + type: string + description: Project name. + organization_id: + type: string + description: Owning organization ID. + slug: + type: string + description: Project slug. + toolset_count: + type: integer + description: Number of active toolsets in the project. + format: int64 + updated_at: + type: string + format: date-time + description: Full project detail surfaced to admin operators, including aggregated counts of child resources. + required: + - id + - name + - slug + - organization_id + - toolset_count + - deployment_count + - http_tool_count + - environment_count + - api_key_count + - assistant_count + - created_at + - updated_at + AdminSession: + type: object + properties: + email: + type: string + name: + type: string + required: + - email + AdminStripeSubscription: + type: object + properties: + cancel_at: + type: string + format: date-time + cancel_at_period_end: + type: boolean + canceled_at: + type: string + format: date-time + current_period_end: + type: string + format: date-time + current_period_start: + type: string + format: date-time + payment_failed: + type: boolean + status: + type: string + enum: + - incomplete + - incomplete_expired + - trialing + - active + - past_due + - canceled + - unpaid + - paused + trial_end: + type: string + format: date-time + trial_start: + type: string + format: date-time + required: + - status + - current_period_start + - current_period_end + - cancel_at_period_end + - payment_failed + AuditLog: + type: object + properties: + acting_client_id: + type: string + description: The registered OAuth client the call authenticated as, when it had one. Absent for calls that carried no OAuth client. + acting_surface: + type: string + description: 'How the change was made: ''dashboard'', ''api_key'', ''platform_mcp'', ''project_assistant'', or ''unknown'' when no surface was identifiable. Always present.' + action: + type: string + actor_display_name: + type: string + actor_id: + type: string + actor_slug: + type: string + actor_type: + type: string + after_snapshot: {} + before_snapshot: {} + created_at: + type: string + description: The creation date of the audit log. + format: date-time + id: + type: string + metadata: + type: object + additionalProperties: true + project_id: + type: string + project_slug: + type: string + subject_display_name: + type: string + subject_id: + type: string + subject_slug: + type: string + subject_type: + type: string + required: + - id + - actor_id + - actor_type + - action + - subject_id + - subject_type + - acting_surface + - created_at + BulkUpdateAccountTypeRequestBody: + type: object + properties: + account_type: + type: string + description: New gram_account_type for every listed organization. + enum: + - free + - pro + - payg + - enterprise + ids: + type: array + items: + type: string + minLength: 1 + description: Organization IDs to update. + minItems: 1 + maxItems: 1000 + required: + - ids + - account_type + CancelStripeSubscriptionRequestBody: + type: object + properties: + organization_id: + type: string + required: + - organization_id + CreateOrganizationRequestBody: + type: object + properties: + name: + type: string + description: Display name for the new organization. + minLength: 1 + required: + - name + DisableOrganizationRequestBody: + type: object + properties: + id: + type: string + description: Organization ID. + minLength: 1 + required: + - id + EnableOrganizationRequestBody: + type: object + properties: + id: + type: string + description: Organization ID. + minLength: 1 + required: + - id + Error: + type: object + properties: + fault: + type: boolean + description: Is the error a server-side fault? + id: + type: string + description: ID is a unique identifier for this particular occurrence of the problem. + example: 123abc + message: + type: string + description: Message is a human-readable explanation specific to this occurrence of the problem. + example: parameter 'p' must be an integer + name: + type: string + description: Name is the name of this class of errors. + example: bad_request + temporary: + type: boolean + description: Is the error temporary? + timeout: + type: boolean + description: Is the error a timeout? + description: unauthorized access + required: + - name + - id + - message + - temporary + - timeout + - fault + x-speakeasy-name-override: ServiceError + ExtendTrialRequestBody: + type: object + properties: + days: + type: integer + description: Number of days to add to the trial's current end date. + format: int64 + minimum: 1 + maximum: 365 + id: + type: string + description: Organization ID. + minLength: 1 + required: + - id + - days + MarkEnterpriseTrialConvertedRequestBody: + type: object + properties: + id: + type: string + description: Organization ID. + minLength: 1 + required: + - id + MarkEnterpriseTrialConvertedResult: + type: object + properties: + converted_at: + type: string + description: The time at which the enterprise trial was recorded as converted. + format: date-time + organization_id: + type: string + description: The converted organization ID. + description: Privacy-minimal result of recording an enterprise trial conversion. + required: + - organization_id + - converted_at + ProductFeatures: + type: object + properties: + ai_platform_push_integrations_enabled: + type: boolean + description: Whether the organization can provision push integrations for AI platforms + authz_challenge_logging_enabled: + type: boolean + description: Whether authz challenge logging to ClickHouse is enabled + consent_tool_filtering_enabled: + type: boolean + description: Whether MCP consent screens offer the tool filtering picker for the organization + custom_model_keys_enabled: + type: boolean + description: Whether the organization can supply its own model provider API keys (BYOK) + customer_managed_encryption_keys_enabled: + type: boolean + description: Whether the organization can manage the external credentials and cloud KMS keys backing customer-managed encryption + device_agent: + type: boolean + description: Whether the organization uses the device agent (any device has polled agent.getPlugins). Derived from device-agent syncs, not an admin-settable feature. + hooks_browser_login_enabled: + type: boolean + description: Whether generated hook plugins may mint per-user keys via the interactive browser login + hooks_fail_open_enabled: + type: boolean + description: Whether hooks fail open when the Speakeasy control plane is unreachable or erroring — blocking policies are not enforced for the duration of the outage + logs_enabled: + type: boolean + description: Whether logging is enabled + platform_mcp_enabled: + type: boolean + description: Whether the organization can use the Gram Platform MCP capability + remote_session_auto_refresh_enabled: + type: boolean + description: Whether consent screens expose automatic remote-session refresh for the organization + remote_session_auto_refresh_enforced_enabled: + type: boolean + description: 'Whether automatic remote-session refresh is enforced as the organization default: forced on for every user, shown locked on consent screens, and applied by the keepalive regardless of per-session preference' + scim_enabled: + type: boolean + description: Whether SCIM/directory sync setup is enabled for the organization + session_capture_enabled: + type: boolean + description: Whether Claude Code session capture is enabled + session_portability_enabled: + type: boolean + description: 'Whether agent session portability is enabled for the organization: session sharing links, move reporting with lineage, and picker title enrichment via the device agent' + skill_capture_metadata_only: + type: boolean + description: Whether skill capture stores activation metadata without requesting manifest content + skills_enabled: + type: boolean + description: Whether the Skills page is enabled for the organization + sso_enabled: + type: boolean + description: Whether SSO setup is enabled for the organization + tool_io_logs_enabled: + type: boolean + description: Whether tool I/O logging is enabled + required: + - logs_enabled + - tool_io_logs_enabled + - session_capture_enabled + - authz_challenge_logging_enabled + - sso_enabled + - scim_enabled + - hooks_browser_login_enabled + - hooks_fail_open_enabled + - custom_model_keys_enabled + - skills_enabled + - skill_capture_metadata_only + - ai_platform_push_integrations_enabled + - platform_mcp_enabled + - customer_managed_encryption_keys_enabled + - remote_session_auto_refresh_enabled + - remote_session_auto_refresh_enforced_enabled + - consent_tool_filtering_enabled + - session_portability_enabled + - device_agent + RearmTrialRequestBody: + type: object + properties: + days: + type: integer + description: Number of days the re-armed trial runs for, counted from now. + format: int64 + minimum: 1 + maximum: 365 + id: + type: string + description: Organization ID. + minLength: 1 + required: + - id + - days + ResumeStripeSubscriptionRequestBody: + type: object + properties: + organization_id: + type: string + required: + - organization_id + SetInferenceKeyMonthlyLimitRequestBody: + type: object + properties: + key_type: + type: string + enum: + - chat + - internal + monthly_credits: + type: integer + format: int64 + minimum: 1 + maximum: 10000 + organization_id: + type: string + required: + - organization_id + - key_type + - monthly_credits + SetOrganizationChatAnalysisSettingsRequestBody: + type: object + properties: + daily_cap: + type: integer + format: int64 + minimum: 0 + maximum: 10000 + enabled: + type: boolean + judge: + type: string + enum: + - work_units + - business_memory + organization_id: + type: string + required: + - organization_id + - judge + - enabled + - daily_cap + SetOrganizationFeatureRequestBody: + type: object + properties: + enabled: + type: boolean + feature_name: + type: string + enum: + - logs + - tool_io_logs + - session_capture + - authz_challenge_logging + - sso + - scim + - hooks_browser_login + - hooks_fail_open + - custom_model_keys + - skills + - skill_capture_metadata_only + - ai_platform_push_integrations + - platform_mcp + - customer_managed_encryption_keys + - remote_session_auto_refresh + - remote_session_auto_refresh_enforced + - consent_tool_filtering + - session_portability + maxLength: 60 + organization_id: + type: string + required: + - organization_id + - feature_name + - enabled + TriggerOrganizationChatAnalysisRequestBody: + type: object + properties: + organization_id: + type: string + required: + - organization_id + UpdateOrganizationRequestBody: + type: object + properties: + account_type: + type: string + description: New gram_account_type (free, pro, payg, or enterprise). + enum: + - free + - pro + - payg + - enterprise + id: + type: string + description: Organization ID. + whitelisted: + type: boolean + description: New whitelisted flag. + required: + - id + securitySchemes: + apikey_header_Authorization: + type: apiKey + description: key based auth. + name: Authorization + in: header + apikey_header_Gram-Key: + type: apiKey + description: key based auth. + name: Gram-Key + in: header + chat_sessions_token_header_Gram-Chat-Session: + type: http + description: Gram Chat Sessions token based auth. + scheme: bearer + function_token_header_Authorization: + type: http + description: Gram Functions token based auth. + scheme: bearer + project_slug_header_Gram-Project: + type: apiKey + description: project slug header auth. + name: Gram-Project + in: header + session_header_Gram-Session: + type: apiKey + description: Session based auth. By cookie or header. + name: Gram-Session + in: header +tags: + - name: admin + description: Operations supporting admin tasks, protected by Google workspace auth. diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 69b7e9e15f0..22aa2bcb883 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,6 +1,8 @@ speakeasyVersion: 1.796.1 sources: {} targets: + gram-admin: + source: Gram-Admin gram-internal: source: Gram-Internal hooks-go: @@ -9,6 +11,15 @@ workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.796.1 sources: + Gram-Admin: + inputs: + - location: server/gen/http/openapi3.yaml + overlays: + - location: overlays/goa-common.yaml + - location: overlays/admin-sdk.yaml + transformations: + - removeUnused: true + output: .speakeasy/out.admin.openapi.yaml Gram-Internal: inputs: - location: server/gen/http/openapi3.yaml @@ -42,6 +53,10 @@ workflow: - removeUnused: true output: .speakeasy/openapi-hooks.yaml targets: + gram-admin: + target: typescript + source: Gram-Admin + output: client/admin/src/sdk gram-internal: target: typescript source: Gram-Internal diff --git a/.speakeasy/workflow.yaml b/.speakeasy/workflow.yaml index c8319c203ed..0c05f661274 100644 --- a/.speakeasy/workflow.yaml +++ b/.speakeasy/workflow.yaml @@ -10,6 +10,15 @@ sources: transformations: - removeUnused: true output: .speakeasy/out.openapi.yaml + Gram-Admin: + inputs: + - location: server/gen/http/openapi3.yaml + overlays: + - location: overlays/goa-common.yaml + - location: overlays/admin-sdk.yaml + transformations: + - removeUnused: true + output: .speakeasy/out.admin.openapi.yaml Gram-Public: inputs: - location: server/gen/http/openapi3.yaml @@ -38,6 +47,10 @@ targets: target: typescript source: Gram-Internal output: client/dashboard/src/sdk + gram-admin: + target: typescript + source: Gram-Admin + output: client/admin/src/sdk hooks-go: target: go source: Hooks-Ingest diff --git a/client/admin/package.json b/client/admin/package.json index f44ef5f0f2a..45dc7fe3ca5 100644 --- a/client/admin/package.json +++ b/client/admin/package.json @@ -7,10 +7,10 @@ "dev": "vite", "build": "vite build", "lint": "aube run lint:format && aube run lint:no-barrels && aube run lint:oxlint && aube run type-check", - "lint:oxlint": "oxlint --type-aware", - "lint:fix": "oxlint --type-aware --fix", + "lint:oxlint": "oxlint --type-aware --ignore-pattern 'src/sdk/**'", + "lint:fix": "oxlint --type-aware --fix --ignore-pattern 'src/sdk/**'", "lint:format": "aube exec oxfmt -- --check .", - "lint:no-barrels": "! grep -rEn '^export \\*' src --include='*.ts' --include='*.tsx' || (echo 'Barrel re-exports (export *) are not allowed. Re-export named symbols instead.' && exit 1)", + "lint:no-barrels": "! grep -rEn '^export \\*' src --include='*.ts' --include='*.tsx' --exclude-dir=sdk || (echo 'Barrel re-exports (export *) are not allowed. Re-export named symbols instead.' && exit 1)", "preview": "vite preview", "test": "vitest run", "test:watch": "vitest", @@ -33,7 +33,8 @@ "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", "tailwindcss": "^4.3.3", - "tw-animate-css": "^1.4.0" + "tw-animate-css": "^1.4.0", + "zod": "^4" }, "devDependencies": { "@tanstack/router-plugin": "1.168.30", diff --git a/client/admin/src/lib/gramAdminApi.ts b/client/admin/src/lib/gramAdminApi.ts index 7337e757cfe..c4cacca6cf9 100644 --- a/client/admin/src/lib/gramAdminApi.ts +++ b/client/admin/src/lib/gramAdminApi.ts @@ -1,3 +1,7 @@ +import { redirectOnUnauthorized as startLoginRedirect } from "@/lib/gramAdminClient"; + +export { isRedirectingToLogin } from "@/lib/gramAdminClient"; + // Gram admin API client. // // This app is served from the same origin as the Gram admin API (the admin @@ -97,14 +101,9 @@ async function gramAdminRequest( // absolute return_to silently loses the page the operator was on. The hash // is left out because the router keeps the whole route in the path and // query. - const returnTo = encodeURIComponent( - window.location.pathname + window.location.search, + startLoginRedirect( + new GramAdminError(401, null, "redirecting to admin login"), ); - redirectingToLogin = true; - window.location.href = `/admin/auth.login?return_to=${returnTo}&prompt=consent`; - // Setting window.location starts the navigation but does not stop the code - // that follows it. Throw to unwind the in-flight call. - throw new GramAdminError(401, null, "redirecting to admin login"); } if (!res.ok) { @@ -149,19 +148,6 @@ async function gramAdminSend(path: string, init?: RequestInit): Promise { await gramAdminRequest(path, init, false); } -// True once gramAdminFetch has sent the browser to the login page. The document -// is on its way out, so no caller should report the failure that caused it. -// -// The module records the navigation instead of reading it back off the failed -// query, because React Query clears the error of a query that holds no data on -// the next refetch, and a refetch on window focus would then reopen the gate -// while the browser is still leaving. -let redirectingToLogin = false; - -export function isRedirectingToLogin(): boolean { - return redirectingToLogin; -} - // Identity of the admin operator that owns the current session. The backend // reads it from the OIDC session record, so it names the identity-provider // account that signed in to this app, not any Gram customer account. diff --git a/client/admin/src/lib/gramAdminClient.test.ts b/client/admin/src/lib/gramAdminClient.test.ts new file mode 100644 index 00000000000..c730dd7670c --- /dev/null +++ b/client/admin/src/lib/gramAdminClient.test.ts @@ -0,0 +1,191 @@ +/// + +import fs from "node:fs"; +import path from "node:path"; +import { afterEach, describe, expect, expectTypeOf, it, vi } from "vitest"; + +const useMutation = vi.hoisted(() => vi.fn()); + +vi.mock("@tanstack/react-query", async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, useMutation }; +}); + +import type { SetOrganizationFeatureRequestBody } from "@gram/admin-client/models/components/setorganizationfeaturerequestbody"; + +import { isRedirectingToLogin as predecessorLatch } from "@/lib/gramAdminApi"; +import * as boundary from "@/lib/gramAdminClient"; + +const unauthorizedBody = JSON.stringify({ + fault: false, + id: "placeholder", + message: "unauthorized", + name: "unauthorized", + temporary: false, + timeout: false, +}); + +afterEach(() => { + useMutation.mockClear(); + vi.unstubAllGlobals(); + vi.restoreAllMocks(); +}); + +describe("generated admin boundary", () => { + it("does not export generated clients or configurable request controls", () => { + expect(Object.keys(boundary).sort()).toEqual([ + "adminSessionQuery", + "isRedirectingToLogin", + "organizationFeaturesQuery", + "redirectOnUnauthorized", + "setAdminOrganizationFeature", + "useSetAdminOrganizationFeatureMutation", + ]); + + expectTypeOf(boundary.adminSessionQuery).parameters.toEqualTypeOf<[]>(); + expectTypeOf(boundary.setAdminOrganizationFeature).parameters.toEqualTypeOf< + [request: SetOrganizationFeatureRequestBody] + >(); + }); + + it("does not allow forged mutation options to replace its key or function", () => { + const forgedMutationFn = vi.fn(); + + boundary.useSetAdminOrganizationFeatureMutation({ + mutationKey: ["forged"], + mutationFn: forgedMutationFn, + } as never); + + expect(useMutation).toHaveBeenCalledWith( + expect.objectContaining({ + mutationKey: [ + "@gram/admin-client", + "admin", + "adminSetOrganizationFeature", + ], + mutationFn: boundary.setAdminOrganizationFeature, + }), + ); + }); + + it("always calls the generated session operation at this origin with ambient cookie behavior", async () => { + const fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ email: "operator@example.test" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + ); + vi.stubGlobal("fetch", fetch); + + const query = boundary.adminSessionQuery(); + await query.queryFn?.({ signal: new AbortController().signal } as never); + + const request = fetch.mock.calls[0]?.[0] as Request; + expect(new URL(request.url).origin).toBe(window.location.origin); + expect(request.credentials).toBe("same-origin"); + expect(request.mode).toBe("cors"); + expect(request.headers.has("Authorization")).toBe(false); + expect(request.headers.has("Cookie")).toBe(false); + }); + + it("redirects a generated read before parsing a malformed 401 body", async () => { + vi.resetModules(); + const freshBoundary = await import("@/lib/gramAdminClient"); + vi.stubGlobal( + "fetch", + vi.fn().mockResolvedValue( + new Response("not json", { + status: 401, + headers: { "Content-Type": "application/json" }, + }), + ), + ); + const href = vi.spyOn(window.location, "href", "set"); + const query = freshBoundary.adminSessionQuery(); + + await expect( + query.queryFn?.({ signal: new AbortController().signal } as never), + ).rejects.toBeInstanceOf(SyntaxError); + + expect(freshBoundary.isRedirectingToLogin()).toBe(true); + expect(href).toHaveBeenCalledOnce(); + }); + + it("redirects one time for redirecting operations and shares the latch", async () => { + vi.stubGlobal( + "fetch", + vi.fn().mockImplementation(() => + Promise.resolve( + new Response(unauthorizedBody, { + status: 401, + headers: { "Content-Type": "application/json" }, + }), + ), + ), + ); + const href = vi.spyOn(window.location, "href", "set"); + const query = boundary.adminSessionQuery(); + + await expect( + query.queryFn?.({ signal: new AbortController().signal } as never), + ).rejects.toMatchObject({ statusCode: 401 }); + await expect( + query.queryFn?.({ signal: new AbortController().signal } as never), + ).rejects.toMatchObject({ statusCode: 401 }); + + expect(boundary.isRedirectingToLogin()).toBe(true); + expect(predecessorLatch()).toBe(true); + expect(href).toHaveBeenCalledOnce(); + expect(href).toHaveBeenCalledWith( + expect.stringMatching( + /^\/admin\/auth\.login\?return_to=.*&prompt=consent$/, + ), + ); + }); + + it("surfaces a feature mutation 401 without redirecting", async () => { + vi.resetModules(); + const freshBoundary = await import("@/lib/gramAdminClient"); + vi.stubGlobal( + "fetch", + vi.fn().mockResolvedValue( + new Response(unauthorizedBody, { + status: 401, + headers: { "Content-Type": "application/json" }, + }), + ), + ); + const href = vi.spyOn(window.location, "href", "set"); + + await expect( + freshBoundary.setAdminOrganizationFeature({ + organizationId: "org_1", + featureName: "sso", + enabled: true, + }), + ).rejects.toMatchObject({ statusCode: 401 }); + + expect(freshBoundary.isRedirectingToLogin()).toBe(false); + expect(href).not.toHaveBeenCalled(); + }); + + it("keeps global query retries disabled and dashboard handoff as form POST navigation", () => { + const src = path.resolve( + path.dirname(new URL(import.meta.url).pathname), + "..", + ); + const main = fs.readFileSync(path.join(src, "main.tsx"), "utf8"); + const recordHeader = fs.readFileSync( + path.join(src, "pages/organization/RecordHeader.tsx"), + "utf8", + ); + + expect(main).toMatch( + /defaultOptions\s*:\s*\{\s*queries\s*:\s*\{\s*retry\s*:\s*false,?\s*\},?\s*\}/, + ); + expect(recordHeader).toMatch( + / + startLoginRedirect(response), +); +const redirectingClient = new GramCore({ + serverURL: window.location.origin, + httpClient: redirectingHTTPClient, +}); + +let redirectingToLogin = false; + +export function isRedirectingToLogin(): boolean { + return redirectingToLogin; +} + +function statusCode(error: unknown): number | undefined { + if (!error || typeof error !== "object") return undefined; + if ("statusCode" in error && typeof error.statusCode === "number") { + return error.statusCode; + } + if ("status" in error && typeof error.status === "number") { + return error.status; + } + return undefined; +} + +function startLoginRedirect(error: unknown): void { + if (statusCode(error) === 401 && !redirectingToLogin) { + const returnTo = encodeURIComponent( + window.location.pathname + window.location.search, + ); + redirectingToLogin = true; + window.location.href = `/admin/auth.login?return_to=${returnTo}&prompt=consent`; + } +} + +// Shared by generated operations and the handwritten predecessor during the +// consumer migration. Assignment starts navigation but does not unwind callers, +// so the original error remains the operation result. +export function redirectOnUnauthorized(error: unknown): never { + startLoginRedirect(error); + throw error; +} + +async function redirecting(operation: Promise): Promise { + try { + return await operation; + } catch (error) { + return redirectOnUnauthorized(error); + } +} + +function createAdminSessionQuery() { + const generated = buildAdminGetSessionQuery(redirectingClient); + return queryOptions({ + ...generated, + queryFn: (context) => redirecting(generated.queryFn(context)), + staleTime: Infinity, + }); +} + +export function adminSessionQuery(): ReturnType< + typeof createAdminSessionQuery +> { + return createAdminSessionQuery(); +} + +function createOrganizationFeaturesQuery(organizationId: string) { + const request: AdminGetOrganizationFeaturesRequest = { organizationId }; + const generated = buildAdminOrganizationFeaturesQuery( + redirectingClient, + request, + ); + return queryOptions({ + ...generated, + queryFn: (context) => redirecting(generated.queryFn(context)), + }); +} + +export function organizationFeaturesQuery( + organizationId: string, +): ReturnType { + return createOrganizationFeaturesQuery(organizationId); +} + +// Feature writes preserve their predecessor's in-place 401 behavior. No raw +// generated RequestOptions are accepted or forwarded. +const generatedFeatureMutation = + buildSetAdminOrganizationFeatureMutation(mutationClient); + +export function setAdminOrganizationFeature( + request: SetOrganizationFeatureRequestBody, +): Promise { + return generatedFeatureMutation.mutationFn({ request }); +} + +type SetFeatureMutationOptions = Omit< + UseMutationOptions, + "mutationFn" | "mutationKey" +>; + +export function useSetAdminOrganizationFeatureMutation( + options?: SetFeatureMutationOptions, +): UseMutationResult< + ProductFeatures, + Error, + SetOrganizationFeatureRequestBody +> { + return useMutation({ + ...options, + mutationKey: ["@gram/admin-client", "admin", "adminSetOrganizationFeature"], + mutationFn: setAdminOrganizationFeature, + }); +} diff --git a/client/admin/src/pages/organization/Overview.tsx b/client/admin/src/pages/organization/Overview.tsx index f05de4fad77..248da36e707 100644 --- a/client/admin/src/pages/organization/Overview.tsx +++ b/client/admin/src/pages/organization/Overview.tsx @@ -197,7 +197,9 @@ export function Overview({ org }: { org: AdminOrganization }): JSX.Element { const restoreConversionFocus = (): void => { // Controlled dialogs can skip close-autofocus when Presence unmounts. This // second path runs after React disconnects the focused dialog control. - setTimeout(() => focusConversionTarget()); + setTimeout(() => { + focusConversionTarget(); + }); }; const restoreConversionFocusFromDialog = (event: Event): void => { diff --git a/client/admin/src/pages/organizations/OrganizationActions.tsx b/client/admin/src/pages/organizations/OrganizationActions.tsx index f9b2d4a2e71..49edc6116e4 100644 --- a/client/admin/src/pages/organizations/OrganizationActions.tsx +++ b/client/admin/src/pages/organizations/OrganizationActions.tsx @@ -209,7 +209,9 @@ export function OrganizationActions({ // The controlled dialog can unmount without Radix firing close-autofocus in // a browser. Restore after React disconnects the dialog control instead of // relying on DialogTrigger behavior these dialogs do not have. - setTimeout(() => focusOrigin(control)); + setTimeout(() => { + focusOrigin(control); + }); }; const closeAfterWrite = (): void => { diff --git a/client/admin/src/sdk/.genignore b/client/admin/src/sdk/.genignore new file mode 100644 index 00000000000..c217ced85e1 --- /dev/null +++ b/client/admin/src/sdk/.genignore @@ -0,0 +1,19 @@ +# Files managed manually rather than by the SDK generator. +# https://www.speakeasy.com/docs/sdks/customize/code/custom-code/genignore + +# Speakeasy emits a .gitattributes that marks generated TS as linguist-generated=false. +# We intentionally don't keep it, so stop the generator from re-adding it. +/.gitattributes + +/.devcontainer +/docs +/examples +/.npmignore +/.oxfmtrc.json +/.oxlintrc.json +/package.json +/jsr.json +/tsconfig.json +/*.md +!/FUNCTIONS.md +!/REACT_QUERY.md \ No newline at end of file diff --git a/client/admin/src/sdk/.gitignore b/client/admin/src/sdk/.gitignore new file mode 100644 index 00000000000..5fb2934d091 --- /dev/null +++ b/client/admin/src/sdk/.gitignore @@ -0,0 +1,33 @@ +/examples/node_modules +.env +.env.local +.env.*.local +/models +/models/errors +/types +/node_modules +/lib +/sdk +/funcs +/react-query +/mcp-server +/hooks +/index.* +/core.* +/bin +/cjs +/esm +/dist +/.tsbuildinfo +/.eslintcache +/.tshy +/.tshy-* +/__tests__ +.DS_Store +**/.speakeasy/temp/ +**/.speakeasy/logs/ +.DS_Store +/.speakeasy/reports +# Per-run manifest written only by degraded (offline/no-API-key) speakeasy +# generation; a full CI generation does not produce it. +/.speakeasy/generated-files-*.lock diff --git a/client/admin/src/sdk/.oxfmtrc.json b/client/admin/src/sdk/.oxfmtrc.json new file mode 100644 index 00000000000..b3bfa5b517a --- /dev/null +++ b/client/admin/src/sdk/.oxfmtrc.json @@ -0,0 +1,3 @@ +{ + "ignorePatterns": ["**/*"] +} diff --git a/client/admin/src/sdk/.oxlintrc.json b/client/admin/src/sdk/.oxlintrc.json new file mode 100644 index 00000000000..6ee29210100 --- /dev/null +++ b/client/admin/src/sdk/.oxlintrc.json @@ -0,0 +1,14 @@ +{ + "rules": { + "no-constant-condition": "off", + "no-useless-escape": "off", + "no-unused-private-class-members": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-useless-empty-export": "off", + "unicorn/no-thenable": "off", + "unicorn/no-empty-file": "off" + } +} diff --git a/client/admin/src/sdk/.speakeasy/gen.lock b/client/admin/src/sdk/.speakeasy/gen.lock new file mode 100644 index 00000000000..c2bb423cc6b --- /dev/null +++ b/client/admin/src/sdk/.speakeasy/gen.lock @@ -0,0 +1,508 @@ +lockVersion: 2.0.0 +id: 28456435-1d04-45f4-ad18-f45f4724a5a5 +management: + docVersion: 0.0.1 + speakeasyVersion: 1.796.1 + generationVersion: 2.933.0 + releaseVersion: 0.33.8 +features: + typescript: + additionalDependencies: 0.1.0 + core: 3.31.6 + defaultEnabledRetries: 0.1.0 + devContainers: 2.90.1 + enumUnions: 0.1.0 + envVarSecurityUsage: 0.1.2 + globalSecurityCallbacks: 0.1.0 + globalServerURLs: 2.83.1 + ignores: 2.81.1 + methodArguments: 0.1.2 + nameOverrides: 2.81.4 + pagination: 2.83.2 + reactQueryHooks: 0.3.0 + responseFormat: 0.3.0 + retries: 2.83.1 + sdkHooks: 0.4.0 +trackedFiles: + FUNCTIONS.md: {} + REACT_QUERY.md: {} + src/core.ts: {} + src/funcs/adminBulkUpdateAccountType.ts: {} + src/funcs/adminCancelStripeSubscription.ts: {} + src/funcs/adminCreateOrganization.ts: {} + src/funcs/adminDisableOrganization.ts: {} + src/funcs/adminEnableOrganization.ts: {} + src/funcs/adminExtendTrial.ts: {} + src/funcs/adminGetInferenceKeys.ts: {} + src/funcs/adminGetInferenceSpendHistory.ts: {} + src/funcs/adminGetOrganization.ts: {} + src/funcs/adminGetOrganizationChatAnalysisSettings.ts: {} + src/funcs/adminGetOrganizationFeatures.ts: {} + src/funcs/adminGetOrganizationStats.ts: {} + src/funcs/adminGetPaygBillingSummary.ts: {} + src/funcs/adminGetProject.ts: {} + src/funcs/adminGetSession.ts: {} + src/funcs/adminGetStripeSubscription.ts: {} + src/funcs/adminListOrganizationActivity.ts: {} + src/funcs/adminListOrganizationMembers.ts: {} + src/funcs/adminListOrganizationProjects.ts: {} + src/funcs/adminListOrganizations.ts: {} + src/funcs/adminLogout.ts: {} + src/funcs/adminMarkEnterpriseTrialConverted.ts: {} + src/funcs/adminRearmTrial.ts: {} + src/funcs/adminResumeStripeSubscription.ts: {} + src/funcs/adminSetInferenceKeyMonthlyLimit.ts: {} + src/funcs/adminSetOrganizationChatAnalysisSettings.ts: {} + src/funcs/adminSetOrganizationFeature.ts: {} + src/funcs/adminTriggerOrganizationChatAnalysis.ts: {} + src/funcs/adminUpdateOrganization.ts: {} + src/hooks/hooks.ts: {} + src/hooks/types.ts: {} + src/index.ts: {} + src/lib/base64.ts: {} + src/lib/config.ts: {} + src/lib/encodings.ts: {} + src/lib/env.ts: {} + src/lib/files.ts: {} + src/lib/http.ts: {} + src/lib/logger.ts: {} + src/lib/matchers.ts: {} + src/lib/primitives.ts: {} + src/lib/retries.ts: {} + src/lib/schemas.ts: {} + src/lib/sdks.ts: {} + src/lib/security.ts: {} + src/lib/url.ts: {} + src/models/components/adminbulkupdateaccounttyperesult.ts: {} + src/models/components/adminchatanalysissettings.ts: {} + src/models/components/adminchatanalysistriggerresult.ts: {} + src/models/components/admininferencekey.ts: {} + src/models/components/admininferencekeylimit.ts: {} + src/models/components/admininferencespendmonth.ts: {} + src/models/components/adminlistorganizationactivityresult.ts: {} + src/models/components/adminlistorganizationmembersresult.ts: {} + src/models/components/adminlistorganizationprojectsresult.ts: {} + src/models/components/adminlistorganizationsresult.ts: {} + src/models/components/adminorganization.ts: {} + src/models/components/adminorganizationmember.ts: {} + src/models/components/adminorganizationstats.ts: {} + src/models/components/adminpaygbillingsummary.ts: {} + src/models/components/adminproject.ts: {} + src/models/components/adminprojectdetail.ts: {} + src/models/components/adminsession.ts: {} + src/models/components/adminstripesubscription.ts: {} + src/models/components/auditlog.ts: {} + src/models/components/bulkupdateaccounttyperequestbody.ts: {} + src/models/components/cancelstripesubscriptionrequestbody.ts: {} + src/models/components/createorganizationrequestbody.ts: {} + src/models/components/disableorganizationrequestbody.ts: {} + src/models/components/enableorganizationrequestbody.ts: {} + src/models/components/extendtrialrequestbody.ts: {} + src/models/components/markenterprisetrialconvertedrequestbody.ts: {} + src/models/components/markenterprisetrialconvertedresult.ts: {} + src/models/components/productfeatures.ts: {} + src/models/components/rearmtrialrequestbody.ts: {} + src/models/components/resumestripesubscriptionrequestbody.ts: {} + src/models/components/setinferencekeymonthlylimitrequestbody.ts: {} + src/models/components/setorganizationchatanalysissettingsrequestbody.ts: {} + src/models/components/setorganizationfeaturerequestbody.ts: {} + src/models/components/triggerorganizationchatanalysisrequestbody.ts: {} + src/models/components/updateorganizationrequestbody.ts: {} + src/models/errors/apierror.ts: {} + src/models/errors/gramerror.ts: {} + src/models/errors/httpclienterrors.ts: {} + src/models/errors/responsevalidationerror.ts: {} + src/models/errors/sdkvalidationerror.ts: {} + src/models/errors/serviceerror.ts: {} + src/models/operations/admingetinferencekeys.ts: {} + src/models/operations/admingetinferencespendhistory.ts: {} + src/models/operations/admingetorganization.ts: {} + src/models/operations/admingetorganizationchatanalysissettings.ts: {} + src/models/operations/admingetorganizationfeatures.ts: {} + src/models/operations/admingetpaygbillingsummary.ts: {} + src/models/operations/admingetproject.ts: {} + src/models/operations/admingetstripesubscription.ts: {} + src/models/operations/adminlistorganizationactivity.ts: {} + src/models/operations/adminlistorganizationmembers.ts: {} + src/models/operations/adminlistorganizationprojects.ts: {} + src/models/operations/adminlistorganizations.ts: {} + src/react-query/_context.tsx: {} + src/react-query/_types.ts: {} + src/react-query/adminBulkUpdateAccountType.ts: {} + src/react-query/adminCancelStripeSubscription.ts: {} + src/react-query/adminCreateOrganization.ts: {} + src/react-query/adminDisableOrganization.ts: {} + src/react-query/adminEnableOrganization.ts: {} + src/react-query/adminExtendTrial.ts: {} + src/react-query/adminGetInferenceKeys.core.ts: {} + src/react-query/adminGetInferenceKeys.ts: {} + src/react-query/adminGetInferenceSpendHistory.core.ts: {} + src/react-query/adminGetInferenceSpendHistory.ts: {} + src/react-query/adminGetOrganization.core.ts: {} + src/react-query/adminGetOrganization.ts: {} + src/react-query/adminGetOrganizationChatAnalysisSettings.core.ts: {} + src/react-query/adminGetOrganizationChatAnalysisSettings.ts: {} + src/react-query/adminGetOrganizationStats.core.ts: {} + src/react-query/adminGetOrganizationStats.ts: {} + src/react-query/adminGetPaygBillingSummary.core.ts: {} + src/react-query/adminGetPaygBillingSummary.ts: {} + src/react-query/adminGetProject.core.ts: {} + src/react-query/adminGetProject.ts: {} + src/react-query/adminGetSession.core.ts: {} + src/react-query/adminGetSession.ts: {} + src/react-query/adminGetStripeSubscription.core.ts: {} + src/react-query/adminGetStripeSubscription.ts: {} + src/react-query/adminListOrganizationActivity.core.ts: {} + src/react-query/adminListOrganizationActivity.ts: {} + src/react-query/adminListOrganizationMembers.core.ts: {} + src/react-query/adminListOrganizationMembers.ts: {} + src/react-query/adminListOrganizationProjects.core.ts: {} + src/react-query/adminListOrganizationProjects.ts: {} + src/react-query/adminListOrganizations.core.ts: {} + src/react-query/adminListOrganizations.ts: {} + src/react-query/adminLogout.ts: {} + src/react-query/adminMarkEnterpriseTrialConverted.ts: {} + src/react-query/adminOrganizationFeatures.core.ts: {} + src/react-query/adminOrganizationFeatures.ts: {} + src/react-query/adminRearmTrial.ts: {} + src/react-query/adminResumeStripeSubscription.ts: {} + src/react-query/adminSetInferenceKeyMonthlyLimit.ts: {} + src/react-query/adminSetOrganizationChatAnalysisSettings.ts: {} + src/react-query/adminTriggerOrganizationChatAnalysis.ts: {} + src/react-query/adminUpdateOrganization.ts: {} + src/react-query/index.ts: {} + src/react-query/setAdminOrganizationFeature.ts: {} + src/sdk/admin.ts: {} + src/sdk/sdk.ts: {} + src/types/async.ts: {} + src/types/blobs.ts: {} + src/types/constdatetime.ts: {} + src/types/enums.ts: {} + src/types/fp.ts: {} + src/types/operations.ts: {} + src/types/rfcdate.ts: {} + src/types/streams.ts: {} + src/types/unrecognized.ts: {} +examples: + adminBulkUpdateAccountType: + speakeasy-default-admin-bulk-update-account-type: + requestBody: + application/json: {"account_type": "pro", "ids": ["", "", ""]} + responses: + "200": + application/json: {"missing_ids": ["", ""], "updated_ids": ["", ""]} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminCancelStripeSubscription: + speakeasy-default-admin-cancel-stripe-subscription: + requestBody: + application/json: {"organization_id": ""} + responses: + "200": + application/json: {"cancel_at_period_end": false, "current_period_end": "2025-08-22T18:39:55.519Z", "current_period_start": "2024-05-10T03:23:28.687Z", "payment_failed": true, "status": "trialing"} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminCreateOrganization: + speakeasy-default-admin-create-organization: + requestBody: + application/json: {"name": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2026-04-25T22:31:08.399Z", "id": "", "member_count": 479220, "name": "", "slug": "", "updated_at": "2026-02-08T04:37:48.396Z", "whitelisted": false} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + adminDisableOrganization: + speakeasy-default-admin-disable-organization: + requestBody: + application/json: {"id": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2024-08-26T05:04:39.814Z", "id": "", "member_count": 952695, "name": "", "slug": "", "updated_at": "2025-06-25T20:07:54.737Z", "whitelisted": false} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + adminEnableOrganization: + speakeasy-default-admin-enable-organization: + requestBody: + application/json: {"id": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2025-11-13T13:09:17.603Z", "id": "", "member_count": 10607, "name": "", "slug": "", "updated_at": "2026-08-01T04:20:06.780Z", "whitelisted": true} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminExtendTrial: + speakeasy-default-admin-extend-trial: + requestBody: + application/json: {"days": 407458, "id": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2024-11-25T09:55:18.007Z", "id": "", "member_count": 797561, "name": "", "slug": "", "updated_at": "2025-08-13T19:34:29.924Z", "whitelisted": false} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + adminGetInferenceKeys: + speakeasy-default-admin-get-inference-keys: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: [{"credits_used": 3496.71, "disable_causes_classified": true, "disabled": true, "key_type": "", "monthly_credits": 635244}] + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminGetInferenceSpendHistory: + speakeasy-default-admin-get-inference-spend-history: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: [{"period_end": "2025-05-06", "period_start": "2025-08-23", "spend_usd": ""}] + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminGetOrganization: + speakeasy-default-admin-get-organization: + parameters: + query: + id_or_slug: "" + responses: + "200": + application/json: {"account_type": "", "created_at": "2026-12-05T06:45:37.658Z", "id": "", "member_count": 207672, "name": "", "slug": "", "updated_at": "2024-12-21T22:32:48.688Z", "whitelisted": false} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminGetOrganizationChatAnalysisSettings: + speakeasy-default-admin-get-organization-chat-analysis-settings: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"business_memory_daily_cap": 440854, "business_memory_enabled": true, "is_default": true, "organization_id": "", "work_units_daily_cap": 452185, "work_units_enabled": true} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminGetOrganizationFeatures: + speakeasy-default-admin-get-organization-features: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"ai_platform_push_integrations_enabled": false, "authz_challenge_logging_enabled": false, "consent_tool_filtering_enabled": true, "custom_model_keys_enabled": true, "customer_managed_encryption_keys_enabled": true, "device_agent": true, "hooks_browser_login_enabled": true, "hooks_fail_open_enabled": true, "logs_enabled": true, "platform_mcp_enabled": false, "remote_session_auto_refresh_enabled": false, "remote_session_auto_refresh_enforced_enabled": false, "scim_enabled": false, "session_capture_enabled": false, "session_portability_enabled": false, "skill_capture_metadata_only": false, "skills_enabled": false, "sso_enabled": true, "tool_io_logs_enabled": true} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminGetOrganizationStats: + speakeasy-default-admin-get-organization-stats: + responses: + "200": + application/json: {"created_last_7_days": 757990, "customers": 363815, "customers_created_last_7_days": 950793, "disabled": 972479, "disabled_last_7_days": 201493, "total": 778656, "trials_ending_soon": 515987} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminGetPaygBillingSummary: + speakeasy-default-admin-get-payg-billing-summary: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"estimated_total_usd": "", "other_inference_spend_usd": "", "period_end": "2026-07-21T11:21:18.623Z", "period_start": "2025-09-06T19:59:31.956Z", "tum_cost_usd": "", "tum_tokens": 397843, "tum_unit_price_usd": ""} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminGetProject: + speakeasy-default-admin-get-project: + parameters: + query: + id_or_slug: "" + responses: + "200": + application/json: {"api_key_count": 206794, "assistant_count": 961450, "created_at": "2025-10-13T09:47:35.317Z", "deployment_count": 711544, "environment_count": 475554, "http_tool_count": 691880, "id": "", "name": "", "organization_id": "", "slug": "", "toolset_count": 170532, "updated_at": "2025-03-26T03:04:23.537Z"} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + adminGetSession: + speakeasy-default-admin-get-session: + responses: + "200": + application/json: {"email": "Wyatt.Crona18@gmail.com"} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminGetStripeSubscription: + speakeasy-default-admin-get-stripe-subscription: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"cancel_at_period_end": true, "current_period_end": "2025-09-11T18:07:59.935Z", "current_period_start": "2026-01-11T06:38:19.761Z", "payment_failed": true, "status": "incomplete_expired"} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminListOrganizationActivity: + speakeasy-default-admin-list-organization-activity: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"logs": [{"acting_surface": "", "action": "", "actor_id": "", "actor_type": "", "created_at": "2025-07-02T03:58:14.417Z", "id": "", "subject_id": "", "subject_type": ""}]} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminListOrganizationMembers: + speakeasy-default-admin-list-organization-members: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"members": [{"created_at": "2026-07-04T02:21:20.209Z", "display_name": "June17", "email": "Eleanora.Wintheiser@hotmail.com", "id": "", "updated_at": "2025-11-26T08:20:41.649Z"}]} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminListOrganizationProjects: + speakeasy-default-admin-list-organization-projects: + parameters: + query: + organization_id: "" + responses: + "200": + application/json: {"projects": [{"created_at": "2026-01-09T21:55:06.458Z", "id": "", "mcp_server_count": 314962, "name": "", "slug": "", "updated_at": "2025-11-23T13:04:15.777Z"}]} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminListOrganizations: + speakeasy-default-admin-list-organizations: + responses: + "200": + application/json: {"organizations": [], "total": 992254} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + adminLogout: + speakeasy-default-admin-logout: + responses: + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminMarkEnterpriseTrialConverted: + speakeasy-default-admin-mark-enterprise-trial-converted: + requestBody: + application/json: {"id": ""} + responses: + "200": + application/json: {"converted_at": "2025-11-22T09:47:40.403Z", "organization_id": ""} + "400": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": false, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminRearmTrial: + speakeasy-default-admin-rearm-trial: + requestBody: + application/json: {"days": 225644, "id": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2026-07-09T05:13:00.469Z", "id": "", "member_count": 418893, "name": "", "slug": "", "updated_at": "2025-12-04T19:10:44.289Z", "whitelisted": true} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminResumeStripeSubscription: + speakeasy-default-admin-resume-stripe-subscription: + requestBody: + application/json: {"organization_id": ""} + responses: + "200": + application/json: {"cancel_at_period_end": false, "current_period_end": "2025-04-19T17:46:16.593Z", "current_period_start": "2026-04-14T16:39:28.016Z", "payment_failed": false, "status": "trialing"} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminSetInferenceKeyMonthlyLimit: + speakeasy-default-admin-set-inference-key-monthly-limit: + requestBody: + application/json: {"key_type": "chat", "monthly_credits": 649153, "organization_id": ""} + responses: + "200": + application/json: {"key_type": "", "monthly_credits": 857083} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminSetOrganizationChatAnalysisSettings: + speakeasy-default-admin-set-organization-chat-analysis-settings: + requestBody: + application/json: {"daily_cap": 488030, "enabled": false, "judge": "work_units", "organization_id": ""} + responses: + "200": + application/json: {"business_memory_daily_cap": 982419, "business_memory_enabled": false, "is_default": false, "organization_id": "", "work_units_daily_cap": 119468, "work_units_enabled": true} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": true} + adminSetOrganizationFeature: + speakeasy-default-admin-set-organization-feature: + requestBody: + application/json: {"enabled": false, "feature_name": "consent_tool_filtering", "organization_id": ""} + responses: + "200": + application/json: {"ai_platform_push_integrations_enabled": false, "authz_challenge_logging_enabled": true, "consent_tool_filtering_enabled": false, "custom_model_keys_enabled": true, "customer_managed_encryption_keys_enabled": false, "device_agent": false, "hooks_browser_login_enabled": false, "hooks_fail_open_enabled": true, "logs_enabled": true, "platform_mcp_enabled": false, "remote_session_auto_refresh_enabled": false, "remote_session_auto_refresh_enforced_enabled": true, "scim_enabled": true, "session_capture_enabled": true, "session_portability_enabled": true, "skill_capture_metadata_only": false, "skills_enabled": false, "sso_enabled": false, "tool_io_logs_enabled": true} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": true} + adminTriggerOrganizationChatAnalysis: + speakeasy-default-admin-trigger-organization-chat-analysis: + requestBody: + application/json: {"organization_id": ""} + responses: + "200": + application/json: {"projects_signaled": 93343} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": false, "timeout": false} + adminUpdateOrganization: + speakeasy-default-admin-update-organization: + requestBody: + application/json: {"id": ""} + responses: + "200": + application/json: {"account_type": "", "created_at": "2025-09-23T01:12:49.084Z", "id": "", "member_count": 997342, "name": "", "slug": "", "updated_at": "2026-04-10T17:39:44.868Z", "whitelisted": false} + "400": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} + "500": + application/json: {"fault": true, "id": "123abc", "message": "parameter 'p' must be an integer", "name": "bad_request", "temporary": true, "timeout": false} +examplesVersion: 1.0.2 +generatedTests: {} diff --git a/client/admin/src/sdk/.speakeasy/gen.yaml b/client/admin/src/sdk/.speakeasy/gen.yaml new file mode 100644 index 00000000000..e8e66627d06 --- /dev/null +++ b/client/admin/src/sdk/.speakeasy/gen.yaml @@ -0,0 +1,107 @@ +configVersion: 2.0.0 +generation: + devContainers: + enabled: true + schemaPath: ../../server/gen/http/openapi3.yaml + sdkClassName: Gram + maintainOpenAPIOrder: true + usageSnippets: + optionalPropertyRendering: withExample + sdkInitStyle: constructor + useClassNamesForArrayFields: true + fixes: + nameResolutionDec2023: true + nameResolutionFeb2025: false + parameterOrderingFeb2024: true + requestResponseComponentNamesFeb2024: true + securityFeb2025: true + sharedErrorComponentsApr2025: false + sharedNestedComponentsJan2026: false + nameOverrideFeb2026: false + auth: + oAuth2ClientCredentialsEnabled: true + oAuth2PasswordEnabled: true + hoistGlobalSecurity: true + inferSSEOverload: true + sdkHooksConfigAccess: true + schemas: + allOfMergeStrategy: shallowMerge + requestBodyFieldName: "" + versioningStrategy: manual + persistentEdits: + enabled: never + tests: + generateTests: true + generateNewTests: false + skipResponseBodyAssertions: false +typescript: + version: 0.33.8 + acceptHeaderEnum: true + additionalDependencies: + dependencies: {} + devDependencies: + '@tanstack/react-query': 'catalog:' + '@types/react': 'catalog:' + '@types/react-dom': 'catalog:' + typescript: 'catalog:' + peerDependencies: {} + additionalPackageJSON: + private: true + additionalScripts: {} + alwaysIncludeInboundAndOutbound: false + apiPromiseHelpers: false + author: Speakeasy + baseErrorName: GramError + clientServerStatusCodesAsErrors: true + compileCommand: + - "true" + constFieldsAlwaysOptional: false + defaultErrorName: APIError + enableCustomCodeRegions: false + enableMCPServer: false + enableReactQuery: true + enumFormat: union + envVarPrefix: GRAM + eventStreamClassName: EventStream + exportZodModelNamespace: false + fixEnumNameSanitization: false + flatAdditionalProperties: false + flattenGlobalSecurity: true + flatteningOrder: parameters-first + formStringArrayEncodeMode: encoded-string + forwardCompatibleEnumsByDefault: false + forwardCompatibleUnionsByDefault: "false" + generateExamples: true + imports: + option: openapi + paths: + callbacks: models/callbacks + errors: models/errors + operations: models/operations + shared: models/components + webhooks: models/webhooks + inferUnionDiscriminators: true + inputModelSuffix: input + jsonpath: rfc9535 + laxMode: strict + legacyFileNaming: true + maxMethodParams: 0 + methodArguments: infer-optional-args + modelPropertyCasing: camel + moduleFormat: esm + multipartArrayFormat: legacy + outputModelSuffix: output + packageName: '@gram/admin-client' + preApplyUnionDiscriminators: true + preserveModelFieldNames: false + privateIdentifierPrefix: '#' + requestExtras: false + responseFormat: flat + sseFlatResponse: false + templateVersion: v2 + unionStrategy: left-to-right + usageSDKInitImports: [] + useIndexModules: false + useOxlint: true + useTsgo: false + zodVersion: v4-mini diff --git a/client/admin/src/sdk/FUNCTIONS.md b/client/admin/src/sdk/FUNCTIONS.md new file mode 100644 index 00000000000..ab71b722174 --- /dev/null +++ b/client/admin/src/sdk/FUNCTIONS.md @@ -0,0 +1,87 @@ +# Standalone Functions + +> [!NOTE] +> This section is useful if you are using a bundler and targeting browsers and +> runtimes where the size of an application affects performance and load times. + +Every method in this SDK is also available as a standalone function. This +alternative API is suitable when targeting the browser or serverless runtimes +and using a bundler to build your application since all unused functionality +will be tree-shaken away. This includes code for unused methods, Zod schemas, +encoding helpers and response handlers. The result is dramatically smaller +impact on the application's final bundle size which grows very slowly as you use +more and more functionality from this SDK. + +Calling methods through the main SDK class remains a valid and generally more +more ergonomic option. Standalone functions represent an optimisation for a +specific category of applications. + +## Example + +```typescript +import { GramCore } from "@gram/admin-client/core.js"; +import { adminLogout } from "@gram/admin-client/funcs/adminLogout.js"; + +// Use `GramCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const gram = new GramCore({ + serverURL: "https://api.example.com", +}); + +async function run() { + const res = await adminLogout(gram); + if (res.ok) { + const { value: result } = res; + + } else { + console.log("adminLogout failed:", res.error); + } +} + +run(); +``` + +## Result types + +Standalone functions differ from SDK methods in that they return a +`Result` type to capture _known errors_ and document them using +the type system. By avoiding throwing errors, application code maintains clear +control flow and error-handling become part of the regular flow of application +code. + +> We use the term "known errors" because standalone functions, and JavaScript +> code in general, can still throw unexpected errors such as `TypeError`s, +> `RangeError`s and `DOMException`s. Exhaustively catching all errors may be +> something this SDK addresses in the future. Nevertheless, there is still a lot +> of benefit from capturing most errors and turning them into values. + +The second reason for this style of programming is because these functions will +typically be used in front-end applications where exception throwing is +sometimes discouraged or considered unidiomatic. React and similar ecosystems +and libraries tend to promote this style of programming so that components +render useful content under all states (loading, success, error and so on). + +The general pattern when calling standalone functions looks like this: + +```typescript +import { Core } from ""; +import { fetchSomething } from "/funcs/fetchSomething.js"; + +const client = new Core(); + +async function run() { + const result = await fetchSomething(client, { id: "123" }); + if (!result.ok) { + // You can throw the error or handle it. It's your choice now. + throw result.error; + } + + console.log(result.value); +} + +run(); +``` + +Notably, `result.error` above will have an explicit type compared to a try-catch +variation where the error in the catch block can only be of type `unknown` (or +`any` depending on your TypeScript settings). \ No newline at end of file diff --git a/client/admin/src/sdk/REACT_QUERY.md b/client/admin/src/sdk/REACT_QUERY.md new file mode 100644 index 00000000000..16add604658 --- /dev/null +++ b/client/admin/src/sdk/REACT_QUERY.md @@ -0,0 +1,340 @@ +# React hooks + +This SDK provides React hooks and utilies for making queries and mutations that +can take the pain out of building front-end applications for the web or React +Native. + +They are built as a thin wrapper around [TanStack Query for React v5][rq], a +powerful, asynchronous state management library. A good understanding of that +library will be very helpful while using them. In addition to hooks, there are +several helper functions that can be used for cache management and data fetching +during server-rendering and in React Server Components. + +## Getting started + +To get started using React hooks, you will need to inject TanStack query and an +SDK instance into your application. Typically, this will be done high up in +your React app at the root or layout component. For example: + +```tsx +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { GramCore } from "@gram/admin-client"; +import { GramProvider } from "@gram/admin-client/react-query"; + +const queryClient = new QueryClient(); +const gram = new GramCore({ + serverURL: "https://api.example.com", +}); + +// Retries are handled by the underlying SDK. +queryClient.setQueryDefaults(["@gram/admin-client"], { retry: false }); +queryClient.setMutationDefaults(["@gram/admin-client"], { retry: false }); + +export function App() { + return ( + + + {/* Your app logic starts here */} + + + ); +} +``` + +## Queries + +Query hooks are the basic building block for fetching data. In addition to +request data, they take the same options as the [`useQuery` hook][use-query] +from TanStack Query. + +[use-query]: https://tanstack.com/query/v5/docs/framework/react/reference/useQuery + +```tsx +import { useAdminGetOrganizationChatAnalysisSettings } from "@gram/admin-client/react-query/adminGetOrganizationChatAnalysisSettings.js"; + +export function Example() { + const { data, error, status } = useAdminGetOrganizationChatAnalysisSettings({ + organizationId: "", + }); + + // Render the UI here... +} +``` + +### Query timeouts and retries + +Since the underlying SDK handles request timeouts and retries, there are a few +more options provided by the query hooks to control these behaviors. + +```tsx +import { useState } from "react"; +import { useAdminGetOrganizationChatAnalysisSettings } from "@gram/admin-client/react-query/adminGetOrganizationChatAnalysisSettings.js"; + +export function ExampleWithOptions() { + const [enabled, setEnabled] = useState(true); + const { data, error, status } = useAdminGetOrganizationChatAnalysisSettings( + { + organizationId: "", + }, + { + // TanStack Query options: + enabled, + staleTime: 60 * 1000, // 1 minute + gcTime: 5 * 60 * 1000, // 5 minutes + + // Request options for the underlying API call: + timeoutMs: 1000, + retryCodes: ["5XX"], + retries: { + strategy: "backoff", + backoff: { + initialInterval: 500, + maxInterval: 10 * 1000, // 10 seconds + exponent: 1.5, + maxElapsedTime: 60 * 1000, // 1 minute + }, + }, + } + ); + + // Render the UI here... +} +``` + + +## Mutations + +Operations that can have side-effects in this SDK are exposed as mutation hooks. +These can be integrated into HTML forms to submit data to the API. They also +take the same options as the [`useMutation` hook][use-mutation] from TanStack +Query. + +[use-mutation]: https://tanstack.com/query/v5/docs/framework/react/reference/useMutation + +```tsx +import { useAdminLogoutMutation } from "@gram/admin-client/react-query/adminLogout.js"; + +export function Example() { + const { mutate, status } = useAdminLogoutMutation(); + + return ( +
{ + e.preventDefault(); + + // Read form data here... + + mutate(); + }} + > + {/* Form fields go here... */} + +
+ ); +} +``` + +### Mutation timeouts and retries + +Since the underlying SDK handles request timeouts and retries, there are a few +more options provided by the mutation hooks to control these behaviors. + +```tsx +import { useAdminLogoutMutation } from "@gram/admin-client/react-query/adminLogout.js"; + +export function ExampleWithOptions() { + const { mutate, status } = useAdminLogoutMutation({ + // TanStack Query options: + networkMode: "online", + gcTime: 5 * 60 * 1000, // 5 minutes + + // Request options for the underlying API call: + timeoutMs: 1000, + retryCodes: ["5XX"], + retries: { + strategy: "backoff", + backoff: { + initialInterval: 500, + maxInterval: 10 * 1000, // 10 seconds + exponent: 1.5, + maxElapsedTime: 60 * 1000, // 1 minute + }, + }, + }); + + // Render the UI here... +} +``` + + +## Cache invalidation + +In many instances, triggering a mutation hook requires invalidating specific +query data currently residing in the TanStack Query's cache. Alongside every +query hook there are two functions that help invalidate cached data: + +```tsx +import { useQueryClient } from "@tanstack/react-query"; +import { invalidateAdminGetOrganizationChatAnalysisSettings, invalidateAllAdminGetOrganizationChatAnalysisSettings } from "@gram/admin-client/react-query/adminGetOrganizationChatAnalysisSettings.js"; +// Replace this with a real mutation +import { useExampleMutation } from "@gram/admin-client/react-query/example.js"; + +export function Example() { + const { queryClient } = useQueryClient(); + const { mutate, status } = useExampleMutation(); + + return ( +
{ + e.preventDefault(); + + const formData = new FormData(e.target); + + mutate(formData, { + onSuccess: () => { + // Invalidate a single cache entry: + invalidateAdminGetOrganizationChatAnalysisSettings(queryClient, /* ... arguments ... */); + // OR, invalidate all cache entries for the query targets: + invalidateAllAdminGetOrganizationChatAnalysisSettings(queryClient); + }, + }); + }} + > + {/* Form fields go here... */} + + +
+ ); +} +``` + + +## Pagination + +Certain queries may have pagination enabled if the underlying API supports it. +In these cases, additional "infinite" query hooks are exposed to help build +infinite scrolling and "load more" user interfaces. + +> [!NOTE] +> +> The original query hooks will still be available and if you are building a +> more explicit pagination UI with page numbers and next/previous buttons then +> those hooks may be more suitable. + +```tsx +import { useAdminListOrganizationActivityInfinite } from "@gram/admin-client/react-query/adminListOrganizationActivity.js"; + +export function Example() { + const { data, error, status, fetchNextPage, hasNextPage } = useAdminListOrganizationActivityInfinite({ + organizationId: "", + }); + + return ( +
+ {/* Render pages here... */} + + {hasNextPage ? ( +
+ +
+ ) : null} +
+ ); +} +``` + + +## Integration with React Suspense + +TanStack Query predates React Suspense and out of the box it does a great job at +exposing the lifecycle of asynchronous tasks. However, if you are already using +Suspense in your app, the default hooks will not trigger suspense boundaries. +This is why the library and, by extension, this SDK also provide equivalent +hooks that integrate neatly with React Suspense. + +```tsx +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ErrorBoundary } from "react-error-boundary"; + +import { GramCore } from "@gram/admin-client"; +import { GramProvider } from "@gram/admin-client/react-query"; +import { useAdminGetOrganizationChatAnalysisSettingsSuspense } from "@gram/admin-client/react-query/adminGetOrganizationChatAnalysisSettings.js"; + +const queryClient = new QueryClient(); +const gram = new GramCore({ + serverURL: "https://api.example.com", +}); + +export function App() { + return ( + + + + {({ reset }) => ( + ( +
+ There was an error!{' '} + +
{error.message}
+
+ )} + onReset={reset} + > + Loading...}> + + +
+ )} +
+
+
+ ); +} + +function Example() { + const { data } = useAdminGetOrganizationChatAnalysisSettingsSuspense({ + organizationId: "", + }); + + // Render the UI here... +} +``` + + +## Server-rendering and React Server Components + +Query hooks are also side-loaded with prefetch helper functions. These functions +can be used to fetch data from the API during server-rendering and in React +Server Components so that it can be available immediately on page load to any +components that use the corresponding hooks: +```tsx +import { + dehydrate, + HydrationBoundary, + QueryClient, +} from "@tanstack/react-query"; +import { GramCore } from "@gram/admin-client"; +import { prefetchAdminGetOrganizationChatAnalysisSettings } from "@gram/admin-client/react-query/adminGetOrganizationChatAnalysisSettings.js"; + +export default async function Page() { + const queryClient = new QueryClient(); + const gram = new GramCore({ + serverURL: "https://api.example.com", + }); + + await prefetchAdminGetOrganizationChatAnalysisSettings(queryClient, gram, { + organizationId: "", + }); + + return ( + // HydrationBoundary is a Client Component, so hydration will happen there. + + {/* Client components under this point will also have data on page load. */} + + ); +} +``` + + +[rq]: https://tanstack.com/query/v5/docs/framework/react/overview \ No newline at end of file diff --git a/client/admin/src/sdk/src/core.ts b/client/admin/src/sdk/src/core.ts new file mode 100644 index 00000000000..ad310872391 --- /dev/null +++ b/client/admin/src/sdk/src/core.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ClientSDK } from "./lib/sdks.js"; + +/** + * A minimal client to use when calling standalone SDK functions. Typically, an + * instance of this class would be instantiated once at the start of an + * application and passed around through some dependency injection mechanism to + * parts of an application that need to make SDK calls. + */ +export class GramCore extends ClientSDK {} diff --git a/client/admin/src/sdk/src/funcs/adminBulkUpdateAccountType.ts b/client/admin/src/sdk/src/funcs/adminBulkUpdateAccountType.ts new file mode 100644 index 00000000000..5882cd599cb --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminBulkUpdateAccountType.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminBulkUpdateAccountTypeResult, + AdminBulkUpdateAccountTypeResult$inboundSchema, +} from "../models/components/adminbulkupdateaccounttyperesult.js"; +import { + BulkUpdateAccountTypeRequestBody, + BulkUpdateAccountTypeRequestBody$outboundSchema, +} from "../models/components/bulkupdateaccounttyperequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * bulkUpdateAccountType admin + * + * @remarks + * Sets one account type on many organizations in a single statement. An ID that matches no organization is reported back rather than failing the batch, so a stale ID costs the operator that row and not the whole call. + */ +export function adminBulkUpdateAccountType( + client: GramCore, + request: BulkUpdateAccountTypeRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminBulkUpdateAccountTypeResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: BulkUpdateAccountTypeRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminBulkUpdateAccountTypeResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(BulkUpdateAccountTypeRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organizations.bulkUpdateAccountType")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminBulkUpdateAccountType", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminBulkUpdateAccountTypeResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminBulkUpdateAccountTypeResult$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminCancelStripeSubscription.ts b/client/admin/src/sdk/src/funcs/adminCancelStripeSubscription.ts new file mode 100644 index 00000000000..de6872cd948 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminCancelStripeSubscription.ts @@ -0,0 +1,178 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminStripeSubscription, + AdminStripeSubscription$inboundSchema, +} from "../models/components/adminstripesubscription.js"; +import { + CancelStripeSubscriptionRequestBody, + CancelStripeSubscriptionRequestBody$outboundSchema, +} from "../models/components/cancelstripesubscriptionrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * cancelStripeSubscription admin + * + * @remarks + * Schedules an organization's PAYG subscription to cancel at period end. + */ +export function adminCancelStripeSubscription( + client: GramCore, + request: CancelStripeSubscriptionRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: CancelStripeSubscriptionRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(CancelStripeSubscriptionRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.cancelStripeSubscription")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminCancelStripeSubscription", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminStripeSubscription$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502, 503], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminCreateOrganization.ts b/client/admin/src/sdk/src/funcs/adminCreateOrganization.ts new file mode 100644 index 00000000000..958e2f633d2 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminCreateOrganization.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + CreateOrganizationRequestBody, + CreateOrganizationRequestBody$outboundSchema, +} from "../models/components/createorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * createOrganization admin + * + * @remarks + * Creates an organization in WorkOS and in Gram, so an operator does not have to leave the admin app for the WorkOS dashboard. The organization starts with no members, is not whitelisted, and gets no trial. Idempotent against the WorkOS organization webhook: the Gram ID is derived from the WorkOS ID, so both writers converge on one row. + */ +export function adminCreateOrganization( + client: GramCore, + request: CreateOrganizationRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: CreateOrganizationRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(CreateOrganizationRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.create")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminCreateOrganization", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminDisableOrganization.ts b/client/admin/src/sdk/src/funcs/adminDisableOrganization.ts new file mode 100644 index 00000000000..01c8658ca54 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminDisableOrganization.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + DisableOrganizationRequestBody, + DisableOrganizationRequestBody$outboundSchema, +} from "../models/components/disableorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * disableOrganization admin + * + * @remarks + * Disables an organization, recording the moment of the action in disabled_at. Idempotent: disabling an already-disabled organization keeps the original timestamp. + */ +export function adminDisableOrganization( + client: GramCore, + request: DisableOrganizationRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: DisableOrganizationRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(DisableOrganizationRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.disable")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminDisableOrganization", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminEnableOrganization.ts b/client/admin/src/sdk/src/funcs/adminEnableOrganization.ts new file mode 100644 index 00000000000..1441ad9ff18 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminEnableOrganization.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + EnableOrganizationRequestBody, + EnableOrganizationRequestBody$outboundSchema, +} from "../models/components/enableorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * enableOrganization admin + * + * @remarks + * Re-enables a disabled organization by clearing disabled_at. Idempotent: an organization that is already active is unaffected. + */ +export function adminEnableOrganization( + client: GramCore, + request: EnableOrganizationRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: EnableOrganizationRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(EnableOrganizationRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.enable")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminEnableOrganization", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminExtendTrial.ts b/client/admin/src/sdk/src/funcs/adminExtendTrial.ts new file mode 100644 index 00000000000..19d22cb9abe --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminExtendTrial.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + ExtendTrialRequestBody, + ExtendTrialRequestBody$outboundSchema, +} from "../models/components/extendtrialrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * extendTrial admin + * + * @remarks + * Extends a running enterprise trial by adding days to its current end date. Only a running trial can be extended: one that has converted, has been demoted, or has already expired is rejected rather than re-armed. + */ +export function adminExtendTrial( + client: GramCore, + request: ExtendTrialRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: ExtendTrialRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(ExtendTrialRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/trial.extend")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminExtendTrial", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetInferenceKeys.ts b/client/admin/src/sdk/src/funcs/adminGetInferenceKeys.ts new file mode 100644 index 00000000000..2acc9192d57 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetInferenceKeys.ts @@ -0,0 +1,181 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminInferenceKey, + AdminInferenceKey$inboundSchema, +} from "../models/components/admininferencekey.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetInferenceKeysRequest, + AdminGetInferenceKeysRequest$outboundSchema, +} from "../models/operations/admingetinferencekeys.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getInferenceKeys admin + * + * @remarks + * Returns the configured state of every materialized platform-managed OpenRouter key for an organization. + */ +export function adminGetInferenceKeys( + client: GramCore, + request: AdminGetInferenceKeysRequest, + options?: RequestOptions, +): APIPromise< + Result< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetInferenceKeysRequest, + options?: RequestOptions, +): Promise< + [ + Result< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(AdminGetInferenceKeysRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.inferenceKeys")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetInferenceKeys", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, z.array(AdminInferenceKey$inboundSchema)), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetInferenceSpendHistory.ts b/client/admin/src/sdk/src/funcs/adminGetInferenceSpendHistory.ts new file mode 100644 index 00000000000..c9bfb41f123 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetInferenceSpendHistory.ts @@ -0,0 +1,182 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminInferenceSpendMonth, + AdminInferenceSpendMonth$inboundSchema, +} from "../models/components/admininferencespendmonth.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetInferenceSpendHistoryRequest, + AdminGetInferenceSpendHistoryRequest$outboundSchema, +} from "../models/operations/admingetinferencespendhistory.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getInferenceSpendHistory admin + * + * @remarks + * Returns up to twelve complete UTC calendar months of recorded inference spend for an organization. + */ +export function adminGetInferenceSpendHistory( + client: GramCore, + request: AdminGetInferenceSpendHistoryRequest, + options?: RequestOptions, +): APIPromise< + Result< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetInferenceSpendHistoryRequest, + options?: RequestOptions, +): Promise< + [ + Result< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(AdminGetInferenceSpendHistoryRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.inferenceSpendHistory")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetInferenceSpendHistory", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + Array, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, z.array(AdminInferenceSpendMonth$inboundSchema)), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetOrganization.ts b/client/admin/src/sdk/src/funcs/adminGetOrganization.ts new file mode 100644 index 00000000000..d7fe9e3099d --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetOrganization.ts @@ -0,0 +1,181 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetOrganizationRequest, + AdminGetOrganizationRequest$outboundSchema, +} from "../models/operations/admingetorganization.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getOrganization admin + * + * @remarks + * Returns full admin details for a single organization by id or slug. + */ +export function adminGetOrganization( + client: GramCore, + request: AdminGetOrganizationRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetOrganizationRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(AdminGetOrganizationRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.get")(); + + const query = encodeFormQuery({ + "id_or_slug": payload.id_or_slug, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetOrganization", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetOrganizationChatAnalysisSettings.ts b/client/admin/src/sdk/src/funcs/adminGetOrganizationChatAnalysisSettings.ts new file mode 100644 index 00000000000..7d6f86baf29 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetOrganizationChatAnalysisSettings.ts @@ -0,0 +1,182 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminChatAnalysisSettings, + AdminChatAnalysisSettings$inboundSchema, +} from "../models/components/adminchatanalysissettings.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetOrganizationChatAnalysisSettingsRequest, + AdminGetOrganizationChatAnalysisSettingsRequest$outboundSchema, +} from "../models/operations/admingetorganizationchatanalysissettings.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getOrganizationChatAnalysisSettings admin + */ +export function adminGetOrganizationChatAnalysisSettings( + client: GramCore, + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse( + AdminGetOrganizationChatAnalysisSettingsRequest$outboundSchema, + value, + ), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.chatAnalysisSettings")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetOrganizationChatAnalysisSettings", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminChatAnalysisSettings$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetOrganizationFeatures.ts b/client/admin/src/sdk/src/funcs/adminGetOrganizationFeatures.ts new file mode 100644 index 00000000000..8c19c2e9a09 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetOrganizationFeatures.ts @@ -0,0 +1,179 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + ProductFeatures, + ProductFeatures$inboundSchema, +} from "../models/components/productfeatures.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetOrganizationFeaturesRequest, + AdminGetOrganizationFeaturesRequest$outboundSchema, +} from "../models/operations/admingetorganizationfeatures.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getOrganizationFeatures admin + */ +export function adminGetOrganizationFeatures( + client: GramCore, + request: AdminGetOrganizationFeaturesRequest, + options?: RequestOptions, +): APIPromise< + Result< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetOrganizationFeaturesRequest, + options?: RequestOptions, +): Promise< + [ + Result< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(AdminGetOrganizationFeaturesRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.features")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetOrganizationFeatures", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, ProductFeatures$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetOrganizationStats.ts b/client/admin/src/sdk/src/funcs/adminGetOrganizationStats.ts new file mode 100644 index 00000000000..32300551068 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetOrganizationStats.ts @@ -0,0 +1,154 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { GramCore } from "../core.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganizationStats, + AdminOrganizationStats$inboundSchema, +} from "../models/components/adminorganizationstats.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getOrganizationStats admin + * + * @remarks + * Returns platform-wide organization counts for the strip above the organizations list. Every figure counts the whole platform: none of them narrows to the caller's list filters, so the strip does not move when an operator filters. + */ +export function adminGetOrganizationStats( + client: GramCore, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganizationStats, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + options, + )); +} + +async function $do( + client: GramCore, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganizationStats, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const path = pathToFunc("/admin/organizations.stats")(); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetOrganizationStats", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganizationStats, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganizationStats$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetPaygBillingSummary.ts b/client/admin/src/sdk/src/funcs/adminGetPaygBillingSummary.ts new file mode 100644 index 00000000000..ff70056a6f5 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetPaygBillingSummary.ts @@ -0,0 +1,181 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminPaygBillingSummary, + AdminPaygBillingSummary$inboundSchema, +} from "../models/components/adminpaygbillingsummary.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetPaygBillingSummaryRequest, + AdminGetPaygBillingSummaryRequest$outboundSchema, +} from "../models/operations/admingetpaygbillingsummary.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getPaygBillingSummary admin + * + * @remarks + * Returns current PAYG usage and estimated cost for an organization. + */ +export function adminGetPaygBillingSummary( + client: GramCore, + request: AdminGetPaygBillingSummaryRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminPaygBillingSummary, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetPaygBillingSummaryRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminPaygBillingSummary, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(AdminGetPaygBillingSummaryRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.paygBillingSummary")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetPaygBillingSummary", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminPaygBillingSummary, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminPaygBillingSummary$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502, 503], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetProject.ts b/client/admin/src/sdk/src/funcs/adminGetProject.ts new file mode 100644 index 00000000000..5142b53b9c0 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetProject.ts @@ -0,0 +1,182 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminProjectDetail, + AdminProjectDetail$inboundSchema, +} from "../models/components/adminprojectdetail.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetProjectRequest, + AdminGetProjectRequest$outboundSchema, +} from "../models/operations/admingetproject.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getProject admin + * + * @remarks + * Returns full admin details for a project by id or slug, including aggregated counts of child resources. + */ +export function adminGetProject( + client: GramCore, + request: AdminGetProjectRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminProjectDetail, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetProjectRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminProjectDetail, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(AdminGetProjectRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/project.get")(); + + const query = encodeFormQuery({ + "id_or_slug": payload.id_or_slug, + "organization_id_or_slug": payload.organization_id_or_slug, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetProject", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminProjectDetail, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminProjectDetail$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetSession.ts b/client/admin/src/sdk/src/funcs/adminGetSession.ts new file mode 100644 index 00000000000..5abac37dd13 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetSession.ts @@ -0,0 +1,151 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { GramCore } from "../core.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminSession, + AdminSession$inboundSchema, +} from "../models/components/adminsession.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getSession admin + */ +export function adminGetSession( + client: GramCore, + options?: RequestOptions, +): APIPromise< + Result< + AdminSession, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + options, + )); +} + +async function $do( + client: GramCore, + options?: RequestOptions, +): Promise< + [ + Result< + AdminSession, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const path = pathToFunc("/admin/session.get")(); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetSession", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminSession, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminSession$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminGetStripeSubscription.ts b/client/admin/src/sdk/src/funcs/adminGetStripeSubscription.ts new file mode 100644 index 00000000000..c3be6f7da58 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminGetStripeSubscription.ts @@ -0,0 +1,181 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminStripeSubscription, + AdminStripeSubscription$inboundSchema, +} from "../models/components/adminstripesubscription.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminGetStripeSubscriptionRequest, + AdminGetStripeSubscriptionRequest$outboundSchema, +} from "../models/operations/admingetstripesubscription.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * getStripeSubscription admin + * + * @remarks + * Returns the live Stripe subscription and payment state for an organization. + */ +export function adminGetStripeSubscription( + client: GramCore, + request: AdminGetStripeSubscriptionRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminGetStripeSubscriptionRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(AdminGetStripeSubscriptionRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.stripeSubscription")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminGetStripeSubscription", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminStripeSubscription$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502, 503], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminListOrganizationActivity.ts b/client/admin/src/sdk/src/funcs/adminListOrganizationActivity.ts new file mode 100644 index 00000000000..220e65a0ddd --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminListOrganizationActivity.ts @@ -0,0 +1,244 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminListOrganizationActivityRequest, + AdminListOrganizationActivityRequest$outboundSchema, + AdminListOrganizationActivityResponse, + AdminListOrganizationActivityResponse$inboundSchema, +} from "../models/operations/adminlistorganizationactivity.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; +import { + createPageIterator, + haltIterator, + PageIterator, + Paginator, +} from "../types/operations.js"; + +/** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ +export function adminListOrganizationActivity( + client: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): APIPromise< + PageIterator< + Result< + AdminListOrganizationActivityResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + { cursor: string } + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): Promise< + [ + PageIterator< + Result< + AdminListOrganizationActivityResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + { cursor: string } + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(AdminListOrganizationActivityRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [haltIterator(parsed), { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.activity")(); + + const query = encodeFormQuery({ + "cursor": payload.cursor, + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminListOrganizationActivity", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [haltIterator(requestRes), { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [haltIterator(doResult), { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result, raw] = await M.match< + AdminListOrganizationActivityResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminListOrganizationActivityResponse$inboundSchema, { + key: "Result", + }), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [haltIterator(result), { + status: "complete", + request: req, + response, + }]; + } + + const nextFunc = ( + responseData: unknown, + ): { + next: Paginator< + Result< + AdminListOrganizationActivityResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > + >; + "~next"?: { cursor: string }; + } => { + const nextCursor = (responseData as { next_cursor?: unknown }).next_cursor; + if (typeof nextCursor !== "string") { + return { next: () => null }; + } + if (nextCursor.trim() === "") { + return { next: () => null }; + } + + const nextVal = () => + adminListOrganizationActivity( + client, + { + ...request, + cursor: nextCursor, + }, + options, + ); + + return { next: nextVal, "~next": { cursor: nextCursor } }; + }; + + const page = { ...result, ...nextFunc(raw) }; + return [{ ...page, ...createPageIterator(page, (v) => !v.ok) }, { + status: "complete", + request: req, + response, + }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminListOrganizationMembers.ts b/client/admin/src/sdk/src/funcs/adminListOrganizationMembers.ts new file mode 100644 index 00000000000..832ba52ed84 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminListOrganizationMembers.ts @@ -0,0 +1,182 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminListOrganizationMembersResult, + AdminListOrganizationMembersResult$inboundSchema, +} from "../models/components/adminlistorganizationmembersresult.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminListOrganizationMembersRequest, + AdminListOrganizationMembersRequest$outboundSchema, +} from "../models/operations/adminlistorganizationmembers.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * listOrganizationMembers admin + * + * @remarks + * Lists members of an organization (admin view, no auth scoping). + */ +export function adminListOrganizationMembers( + client: GramCore, + request: AdminListOrganizationMembersRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminListOrganizationMembersResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminListOrganizationMembersRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminListOrganizationMembersResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(AdminListOrganizationMembersRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.members")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminListOrganizationMembers", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminListOrganizationMembersResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminListOrganizationMembersResult$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminListOrganizationProjects.ts b/client/admin/src/sdk/src/funcs/adminListOrganizationProjects.ts new file mode 100644 index 00000000000..04af29a853c --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminListOrganizationProjects.ts @@ -0,0 +1,182 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminListOrganizationProjectsResult, + AdminListOrganizationProjectsResult$inboundSchema, +} from "../models/components/adminlistorganizationprojectsresult.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminListOrganizationProjectsRequest, + AdminListOrganizationProjectsRequest$outboundSchema, +} from "../models/operations/adminlistorganizationprojects.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * listOrganizationProjects admin + * + * @remarks + * Lists projects belonging to an organization (admin view, no auth scoping). + */ +export function adminListOrganizationProjects( + client: GramCore, + request: AdminListOrganizationProjectsRequest, + options?: RequestOptions, +): APIPromise< + Result< + AdminListOrganizationProjectsResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: AdminListOrganizationProjectsRequest, + options?: RequestOptions, +): Promise< + [ + Result< + AdminListOrganizationProjectsResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(AdminListOrganizationProjectsRequest$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organization.projects")(); + + const query = encodeFormQuery({ + "organization_id": payload.organization_id, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminListOrganizationProjects", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminListOrganizationProjectsResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminListOrganizationProjectsResult$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminListOrganizations.ts b/client/admin/src/sdk/src/funcs/adminListOrganizations.ts new file mode 100644 index 00000000000..1df3687d102 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminListOrganizations.ts @@ -0,0 +1,253 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { + AdminListOrganizationsRequest, + AdminListOrganizationsRequest$outboundSchema, + AdminListOrganizationsResponse, + AdminListOrganizationsResponse$inboundSchema, +} from "../models/operations/adminlistorganizations.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; +import { + createPageIterator, + haltIterator, + PageIterator, + Paginator, +} from "../types/operations.js"; + +/** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ +export function adminListOrganizations( + client: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): APIPromise< + PageIterator< + Result< + AdminListOrganizationsResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + { cursor: string } + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): Promise< + [ + PageIterator< + Result< + AdminListOrganizationsResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + { cursor: string } + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(z.optional(AdminListOrganizationsRequest$outboundSchema), value), + "Input validation failed", + ); + if (!parsed.ok) { + return [haltIterator(parsed), { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/admin/organizations.list")(); + + const query = encodeFormQuery({ + "account_type": payload?.account_type, + "account_types": payload?.account_types, + "cursor": payload?.cursor, + "direction": payload?.direction, + "disabled_states": payload?.disabled_states, + "include_disabled": payload?.include_disabled, + "limit": payload?.limit, + "page": payload?.page, + "q": payload?.q, + "sort": payload?.sort, + "trial_states": payload?.trial_states, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminListOrganizations", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [haltIterator(requestRes), { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [haltIterator(doResult), { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result, raw] = await M.match< + AdminListOrganizationsResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminListOrganizationsResponse$inboundSchema, { + key: "Result", + }), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [haltIterator(result), { + status: "complete", + request: req, + response, + }]; + } + + const nextFunc = ( + responseData: unknown, + ): { + next: Paginator< + Result< + AdminListOrganizationsResponse, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > + >; + "~next"?: { cursor: string }; + } => { + const nextCursor = (responseData as { next_cursor?: unknown }).next_cursor; + if (typeof nextCursor !== "string") { + return { next: () => null }; + } + if (nextCursor.trim() === "") { + return { next: () => null }; + } + + const nextVal = () => + adminListOrganizations( + client, + { + ...request!, + cursor: nextCursor, + }, + options, + ); + + return { next: nextVal, "~next": { cursor: nextCursor } }; + }; + + const page = { ...result, ...nextFunc(raw) }; + return [{ ...page, ...createPageIterator(page, (v) => !v.ok) }, { + status: "complete", + request: req, + response, + }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminLogout.ts b/client/admin/src/sdk/src/funcs/adminLogout.ts new file mode 100644 index 00000000000..58747d54141 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminLogout.ts @@ -0,0 +1,148 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * logout admin + */ +export function adminLogout( + client: GramCore, + options?: RequestOptions, +): APIPromise< + Result< + void, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + options, + )); +} + +async function $do( + client: GramCore, + options?: RequestOptions, +): Promise< + [ + Result< + void, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const path = pathToFunc("/admin/auth.logout")(); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminLogout", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + void, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.nil(204, z.void()), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminMarkEnterpriseTrialConverted.ts b/client/admin/src/sdk/src/funcs/adminMarkEnterpriseTrialConverted.ts new file mode 100644 index 00000000000..69c53af77e4 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminMarkEnterpriseTrialConverted.ts @@ -0,0 +1,178 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + MarkEnterpriseTrialConvertedRequestBody, + MarkEnterpriseTrialConvertedRequestBody$outboundSchema, +} from "../models/components/markenterprisetrialconvertedrequestbody.js"; +import { + MarkEnterpriseTrialConvertedResult, + MarkEnterpriseTrialConvertedResult$inboundSchema, +} from "../models/components/markenterprisetrialconvertedresult.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * markEnterpriseTrialConverted admin + * + * @remarks + * Records that an organization's enterprise trial converted to a signed contract. + */ +export function adminMarkEnterpriseTrialConverted( + client: GramCore, + request: MarkEnterpriseTrialConvertedRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + MarkEnterpriseTrialConvertedResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: MarkEnterpriseTrialConvertedRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + MarkEnterpriseTrialConvertedResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(MarkEnterpriseTrialConvertedRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/trial.convert")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminMarkEnterpriseTrialConverted", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + MarkEnterpriseTrialConvertedResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, MarkEnterpriseTrialConvertedResult$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminRearmTrial.ts b/client/admin/src/sdk/src/funcs/adminRearmTrial.ts new file mode 100644 index 00000000000..a5584609949 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminRearmTrial.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + RearmTrialRequestBody, + RearmTrialRequestBody$outboundSchema, +} from "../models/components/rearmtrialrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * rearmTrial admin + * + * @remarks + * Puts a demoted enterprise trial back on: restores the organization's account type and whitelist flag, revives its model provider keys, and gives the trial a fresh run of the given length counted from now. Only a demoted trial can be re-armed; one that has converted or is already running is rejected. + */ +export function adminRearmTrial( + client: GramCore, + request: RearmTrialRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: RearmTrialRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(RearmTrialRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/trial.rearm")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminRearmTrial", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminResumeStripeSubscription.ts b/client/admin/src/sdk/src/funcs/adminResumeStripeSubscription.ts new file mode 100644 index 00000000000..27dd8d3e646 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminResumeStripeSubscription.ts @@ -0,0 +1,178 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminStripeSubscription, + AdminStripeSubscription$inboundSchema, +} from "../models/components/adminstripesubscription.js"; +import { + ResumeStripeSubscriptionRequestBody, + ResumeStripeSubscriptionRequestBody$outboundSchema, +} from "../models/components/resumestripesubscriptionrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * resumeStripeSubscription admin + * + * @remarks + * Removes a scheduled period-end cancellation from an organization's PAYG subscription. + */ +export function adminResumeStripeSubscription( + client: GramCore, + request: ResumeStripeSubscriptionRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: ResumeStripeSubscriptionRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(ResumeStripeSubscriptionRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.resumeStripeSubscription")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminResumeStripeSubscription", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminStripeSubscription, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminStripeSubscription$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502, 503], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminSetInferenceKeyMonthlyLimit.ts b/client/admin/src/sdk/src/funcs/adminSetInferenceKeyMonthlyLimit.ts new file mode 100644 index 00000000000..2e8b738dc5d --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminSetInferenceKeyMonthlyLimit.ts @@ -0,0 +1,178 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminInferenceKeyLimit, + AdminInferenceKeyLimit$inboundSchema, +} from "../models/components/admininferencekeylimit.js"; +import { + SetInferenceKeyMonthlyLimitRequestBody, + SetInferenceKeyMonthlyLimitRequestBody$outboundSchema, +} from "../models/components/setinferencekeymonthlylimitrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * setInferenceKeyMonthlyLimit admin + * + * @remarks + * Sets the monthly limit for one materialized platform-managed OpenRouter key. + */ +export function adminSetInferenceKeyMonthlyLimit( + client: GramCore, + request: SetInferenceKeyMonthlyLimitRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminInferenceKeyLimit, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: SetInferenceKeyMonthlyLimitRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminInferenceKeyLimit, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(SetInferenceKeyMonthlyLimitRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.setInferenceKeyMonthlyLimit")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminSetInferenceKeyMonthlyLimit", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminInferenceKeyLimit, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminInferenceKeyLimit$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminSetOrganizationChatAnalysisSettings.ts b/client/admin/src/sdk/src/funcs/adminSetOrganizationChatAnalysisSettings.ts new file mode 100644 index 00000000000..277fedb044a --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminSetOrganizationChatAnalysisSettings.ts @@ -0,0 +1,178 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminChatAnalysisSettings, + AdminChatAnalysisSettings$inboundSchema, +} from "../models/components/adminchatanalysissettings.js"; +import { + SetOrganizationChatAnalysisSettingsRequestBody, + SetOrganizationChatAnalysisSettingsRequestBody$outboundSchema, +} from "../models/components/setorganizationchatanalysissettingsrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * setOrganizationChatAnalysisSettings admin + */ +export function adminSetOrganizationChatAnalysisSettings( + client: GramCore, + request: SetOrganizationChatAnalysisSettingsRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: SetOrganizationChatAnalysisSettingsRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse( + SetOrganizationChatAnalysisSettingsRequestBody$outboundSchema, + value, + ), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.chatAnalysisSettings")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminSetOrganizationChatAnalysisSettings", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminChatAnalysisSettings, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminChatAnalysisSettings$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminSetOrganizationFeature.ts b/client/admin/src/sdk/src/funcs/adminSetOrganizationFeature.ts new file mode 100644 index 00000000000..33ff6511201 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminSetOrganizationFeature.ts @@ -0,0 +1,174 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + ProductFeatures, + ProductFeatures$inboundSchema, +} from "../models/components/productfeatures.js"; +import { + SetOrganizationFeatureRequestBody, + SetOrganizationFeatureRequestBody$outboundSchema, +} from "../models/components/setorganizationfeaturerequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * setOrganizationFeature admin + */ +export function adminSetOrganizationFeature( + client: GramCore, + request: SetOrganizationFeatureRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: SetOrganizationFeatureRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(SetOrganizationFeatureRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.features")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminSetOrganizationFeature", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + ProductFeatures, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, ProductFeatures$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminTriggerOrganizationChatAnalysis.ts b/client/admin/src/sdk/src/funcs/adminTriggerOrganizationChatAnalysis.ts new file mode 100644 index 00000000000..3def196b52f --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminTriggerOrganizationChatAnalysis.ts @@ -0,0 +1,175 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminChatAnalysisTriggerResult, + AdminChatAnalysisTriggerResult$inboundSchema, +} from "../models/components/adminchatanalysistriggerresult.js"; +import { + TriggerOrganizationChatAnalysisRequestBody, + TriggerOrganizationChatAnalysisRequestBody$outboundSchema, +} from "../models/components/triggerorganizationchatanalysisrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * triggerOrganizationChatAnalysis admin + */ +export function adminTriggerOrganizationChatAnalysis( + client: GramCore, + request: TriggerOrganizationChatAnalysisRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminChatAnalysisTriggerResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: TriggerOrganizationChatAnalysisRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminChatAnalysisTriggerResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => + z.parse(TriggerOrganizationChatAnalysisRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.chatAnalysisTrigger")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminTriggerOrganizationChatAnalysis", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminChatAnalysisTriggerResult, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminChatAnalysisTriggerResult$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/funcs/adminUpdateOrganization.ts b/client/admin/src/sdk/src/funcs/adminUpdateOrganization.ts new file mode 100644 index 00000000000..c71b6414447 --- /dev/null +++ b/client/admin/src/sdk/src/funcs/adminUpdateOrganization.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import { matchStatusCode } from "../lib/http.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { pathToFunc } from "../lib/url.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "../models/components/adminorganization.js"; +import { + UpdateOrganizationRequestBody, + UpdateOrganizationRequestBody$outboundSchema, +} from "../models/components/updateorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { + ServiceError, + ServiceError$inboundSchema, +} from "../models/errors/serviceerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * updateOrganization admin + * + * @remarks + * Updates admin-managed fields on an organization. At least one of account_type or whitelisted must be supplied. + */ +export function adminUpdateOrganization( + client: GramCore, + request: UpdateOrganizationRequestBody, + options?: RequestOptions, +): APIPromise< + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: GramCore, + request: UpdateOrganizationRequestBody, + options?: RequestOptions, +): Promise< + [ + Result< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => z.parse(UpdateOrganizationRequestBody$outboundSchema, value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/admin/organization.update")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const context = { + options: client._options, + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "adminUpdateOrganization", + oAuth2Scopes: null, + + resolvedSecurity: null, + + securitySource: null, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + isErrorStatusCode: (statusCode: number) => + matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]), + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + AdminOrganization, + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError + >( + M.json(200, AdminOrganization$inboundSchema), + M.jsonErr([400, 401, 403, 404, 409, 415, 422], ServiceError$inboundSchema), + M.jsonErr([500, 502], ServiceError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, req, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/client/admin/src/sdk/src/hooks/hooks.ts b/client/admin/src/sdk/src/hooks/hooks.ts new file mode 100644 index 00000000000..7ed9e0445ac --- /dev/null +++ b/client/admin/src/sdk/src/hooks/hooks.ts @@ -0,0 +1,132 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SDKOptions } from "../lib/config.js"; +import { RequestInput } from "../lib/http.js"; +import { + AfterErrorContext, + AfterErrorHook, + AfterSuccessContext, + AfterSuccessHook, + BeforeCreateRequestContext, + BeforeCreateRequestHook, + BeforeRequestContext, + BeforeRequestHook, + Hook, + Hooks, + SDKInitHook, +} from "./types.js"; + +import { initHooks } from "./registration.js"; + +export class SDKHooks implements Hooks { + sdkInitHooks: SDKInitHook[] = []; + beforeCreateRequestHooks: BeforeCreateRequestHook[] = []; + beforeRequestHooks: BeforeRequestHook[] = []; + afterSuccessHooks: AfterSuccessHook[] = []; + afterErrorHooks: AfterErrorHook[] = []; + + constructor() { + const presetHooks: Array = []; + + for (const hook of presetHooks) { + if ("sdkInit" in hook) { + this.registerSDKInitHook(hook); + } + if ("beforeCreateRequest" in hook) { + this.registerBeforeCreateRequestHook(hook); + } + if ("beforeRequest" in hook) { + this.registerBeforeRequestHook(hook); + } + if ("afterSuccess" in hook) { + this.registerAfterSuccessHook(hook); + } + if ("afterError" in hook) { + this.registerAfterErrorHook(hook); + } + } + initHooks(this); + } + + registerSDKInitHook(hook: SDKInitHook) { + this.sdkInitHooks.push(hook); + } + + registerBeforeCreateRequestHook(hook: BeforeCreateRequestHook) { + this.beforeCreateRequestHooks.push(hook); + } + + registerBeforeRequestHook(hook: BeforeRequestHook) { + this.beforeRequestHooks.push(hook); + } + + registerAfterSuccessHook(hook: AfterSuccessHook) { + this.afterSuccessHooks.push(hook); + } + + registerAfterErrorHook(hook: AfterErrorHook) { + this.afterErrorHooks.push(hook); + } + + sdkInit(opts: SDKOptions): SDKOptions { + return this.sdkInitHooks.reduce((opts, hook) => hook.sdkInit(opts), opts); + } + + beforeCreateRequest( + hookCtx: BeforeCreateRequestContext, + input: RequestInput, + ): RequestInput { + let inp = input; + + for (const hook of this.beforeCreateRequestHooks) { + inp = hook.beforeCreateRequest(hookCtx, inp); + } + + return inp; + } + + async beforeRequest( + hookCtx: BeforeRequestContext, + request: Request, + ): Promise { + let req = request; + + for (const hook of this.beforeRequestHooks) { + req = await hook.beforeRequest(hookCtx, req); + } + + return req; + } + + async afterSuccess( + hookCtx: AfterSuccessContext, + response: Response, + ): Promise { + let res = response; + + for (const hook of this.afterSuccessHooks) { + res = await hook.afterSuccess(hookCtx, res); + } + + return res; + } + + async afterError( + hookCtx: AfterErrorContext, + response: Response | null, + error: unknown, + ): Promise<{ response: Response | null; error: unknown }> { + let res = response; + let err = error; + + for (const hook of this.afterErrorHooks) { + const result = await hook.afterError(hookCtx, res, err); + res = result.response; + err = result.error; + } + + return { response: res, error: err }; + } +} diff --git a/client/admin/src/sdk/src/hooks/registration.ts b/client/admin/src/sdk/src/hooks/registration.ts new file mode 100644 index 00000000000..70649734e83 --- /dev/null +++ b/client/admin/src/sdk/src/hooks/registration.ts @@ -0,0 +1,14 @@ +import { Hooks } from "./types.js"; + +/* + * This file is only ever generated once on the first generation and then is free to be modified. + * Any hooks you wish to add should be registered in the initHooks function. Feel free to define them + * in this file or in separate files in the hooks folder. + */ + +// @ts-expect-error remove this line when you add your first hook and hooks is used +export function initHooks(hooks: Hooks) { + // Add hooks by calling hooks.register{ClientInit/BeforeCreateRequest/BeforeRequest/AfterSuccess/AfterError}Hook + // with an instance of a hook that implements that specific Hook interface + // Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance +} diff --git a/client/admin/src/sdk/src/hooks/types.ts b/client/admin/src/sdk/src/hooks/types.ts new file mode 100644 index 00000000000..a6aa5a25df8 --- /dev/null +++ b/client/admin/src/sdk/src/hooks/types.ts @@ -0,0 +1,108 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SDKOptions } from "../lib/config.js"; +import { RequestInput } from "../lib/http.js"; +import { RetryConfig } from "../lib/retries.js"; +import { SecurityState } from "../lib/security.js"; + +export type HookContext = { + baseURL: string | URL; + operationID: string; + oAuth2Scopes: string[] | null; + securitySource?: any | (() => Promise); + retryConfig: RetryConfig; + resolvedSecurity: SecurityState | null; + options: SDKOptions; + timeoutMs?: number; +}; + +export type Awaitable = T | Promise; + +export type BeforeCreateRequestContext = HookContext & {}; +export type BeforeRequestContext = HookContext & {}; +export type AfterSuccessContext = HookContext & {}; +export type AfterErrorContext = HookContext & {}; + +/** + * SDKInitHook is called when the SDK is initializing. The + * hook can return a new baseURL and HTTP client to be used by the SDK. + */ +export interface SDKInitHook { + sdkInit: (opts: SDKOptions) => SDKOptions; +} + +export interface BeforeCreateRequestHook { + /** + * A hook that is called before the SDK creates a `Request` object. The hook + * can modify how a request is constructed since certain modifications, like + * changing the request URL, cannot be done on a request object directly. + */ + beforeCreateRequest: ( + hookCtx: BeforeCreateRequestContext, + input: RequestInput, + ) => RequestInput; +} + +export interface BeforeRequestHook { + /** + * A hook that is called before the SDK sends a request. The hook can + * introduce instrumentation code such as logging, tracing and metrics or + * replace the request before it is sent or throw an error to stop the + * request from being sent. + */ + beforeRequest: ( + hookCtx: BeforeRequestContext, + request: Request, + ) => Awaitable; +} + +export interface AfterSuccessHook { + /** + * A hook that is called after the SDK receives a response. The hook can + * introduce instrumentation code such as logging, tracing and metrics or + * modify the response before it is handled or throw an error to stop the + * response from being handled. + */ + afterSuccess: ( + hookCtx: AfterSuccessContext, + response: Response, + ) => Awaitable; +} + +export interface AfterErrorHook { + /** + * A hook that is called after the SDK encounters an error, or a + * non-successful response. The hook can introduce instrumentation code such + * as logging, tracing and metrics or modify the response or error values. + */ + afterError: ( + hookCtx: AfterErrorContext, + response: Response | null, + error: unknown, + ) => Awaitable<{ + response: Response | null; + error: unknown; + }>; +} + +export interface Hooks { + /** Registers a hook to be used by the SDK for initialization event. */ + registerSDKInitHook(hook: SDKInitHook): void; + /** Registers a hook to be used by the SDK for to modify `Request` construction. */ + registerBeforeCreateRequestHook(hook: BeforeCreateRequestHook): void; + /** Registers a hook to be used by the SDK for the before request event. */ + registerBeforeRequestHook(hook: BeforeRequestHook): void; + /** Registers a hook to be used by the SDK for the after success event. */ + registerAfterSuccessHook(hook: AfterSuccessHook): void; + /** Registers a hook to be used by the SDK for the after error event. */ + registerAfterErrorHook(hook: AfterErrorHook): void; +} + +export type Hook = + | SDKInitHook + | BeforeCreateRequestHook + | BeforeRequestHook + | AfterSuccessHook + | AfterErrorHook; diff --git a/client/admin/src/sdk/src/index.ts b/client/admin/src/sdk/src/index.ts new file mode 100644 index 00000000000..dbcba164a00 --- /dev/null +++ b/client/admin/src/sdk/src/index.ts @@ -0,0 +1,9 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./lib/config.js"; +export * as files from "./lib/files.js"; +export { HTTPClient } from "./lib/http.js"; +export type { Fetcher, HTTPClientOptions } from "./lib/http.js"; +export * from "./sdk/sdk.js"; diff --git a/client/admin/src/sdk/src/lib/base64.ts b/client/admin/src/sdk/src/lib/base64.ts new file mode 100644 index 00000000000..44be0eae824 --- /dev/null +++ b/client/admin/src/sdk/src/lib/base64.ts @@ -0,0 +1,39 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export function bytesToBase64(u8arr: Uint8Array): string { + return btoa(String.fromCodePoint(...u8arr)); +} + +export function bytesFromBase64(encoded: string): Uint8Array { + return Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0)); +} + +export function stringToBytes(str: string): Uint8Array { + return new TextEncoder().encode(str); +} + +export function stringFromBytes(u8arr: Uint8Array): string { + return new TextDecoder().decode(u8arr); +} + +export function stringToBase64(str: string): string { + return bytesToBase64(stringToBytes(str)); +} + +export function stringFromBase64(b64str: string): string { + return stringFromBytes(bytesFromBase64(b64str)); +} + +export const zodOutbound = z.union([ + z.custom(x => x instanceof Uint8Array), + z.pipe(z.string(), z.transform(stringToBytes)), +]); + +export const zodInbound = z.union([ + z.custom(x => x instanceof Uint8Array), + z.pipe(z.string(), z.transform(bytesFromBase64)), +]); diff --git a/client/admin/src/sdk/src/lib/config.ts b/client/admin/src/sdk/src/lib/config.ts new file mode 100644 index 00000000000..37476be4f1f --- /dev/null +++ b/client/admin/src/sdk/src/lib/config.ts @@ -0,0 +1,47 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { HTTPClient } from "./http.js"; +import { Logger } from "./logger.js"; +import { RetryConfig } from "./retries.js"; +import { pathToFunc } from "./url.js"; + +export type SDKOptions = { + httpClient?: HTTPClient; + /** + * Specifies the server URL to be used by the SDK + */ + serverURL: string; + /** + * Allows overriding the default user agent used by the SDK + */ + userAgent?: string | undefined; + /** + * Allows overriding the default retry config used by the SDK + */ + retryConfig?: RetryConfig; + timeoutMs?: number; + debugLogger?: Logger; +}; + +export function serverURLFromOptions(options: SDKOptions): URL | null { + const serverURL = options.serverURL; + + if (!serverURL) { + return null; + } + + const params: Record = {}; + + const u = pathToFunc(serverURL)(params); + return new URL(u); +} + +export const SDK_METADATA = { + language: "typescript", + openapiDocVersion: "0.0.1", + sdkVersion: "0.33.8", + genVersion: "2.933.0", + userAgent: "speakeasy-sdk/typescript 0.33.8 2.933.0 0.0.1 @gram/admin-client", +} as const; diff --git a/client/admin/src/sdk/src/lib/encodings.ts b/client/admin/src/sdk/src/lib/encodings.ts new file mode 100644 index 00000000000..d6e751fe6a9 --- /dev/null +++ b/client/admin/src/sdk/src/lib/encodings.ts @@ -0,0 +1,560 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { bytesToBase64 } from "./base64.js"; +import { isPlainObject } from "./primitives.js"; + +export class EncodingError extends Error { + constructor(message: string) { + super(message); + this.name = "EncodingError"; + } +} + +export type CharEncoding = "percent" | "percentExceptReserved" | "none"; + +const reservedEscapes = /%(2[346bcf]|3[abdf]|40|5[bd])/gi; + +function encodeKeyChars( + v: string, + charEncoding: CharEncoding | undefined, +): string { + return encodeChars( + v, + charEncoding === "percentExceptReserved" ? "percent" : charEncoding, + ); +} + +function encodeChars( + v: string, + charEncoding: CharEncoding | undefined, +): string { + switch (charEncoding) { + case "percent": + return encodeURIComponent(v); + case "percentExceptReserved": + return encodeURIComponent(v).replace( + reservedEscapes, + (m) => decodeURIComponent(m), + ); + default: + return v; + } +} + +export function encodeMatrix( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +): string | undefined { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue: string | null | undefined = null; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(","); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `,${encodeString(k)},${encodeValue(v)}`; + }); + encValue = mapped?.join("").slice(1); + } else { + encValue = `${encodeValue(pv)}`; + } + + if (encValue == null) { + return; + } + + const keyPrefix = encodeKeyChars(pk, options?.charEncoding); + tmp = `${keyPrefix}=${encValue}`; + // trim trailing '=' if value was empty + if (tmp === `${keyPrefix}=`) { + tmp = tmp.slice(0, -1); + } + + // If we end up with the nothing then skip forward + if (!tmp) { + return; + } + + out += `;${tmp}`; + }); + + return out; +} + +export function encodeLabel( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +): string | undefined { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let encValue: string | null | undefined = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join("."); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `.${encodeString(k)}.${encodeValue(v)}`; + }); + encValue = mapped?.join("").slice(1); + } else { + const k = options?.explode && isPlainObject(value) + ? `${encodeKeyChars(pk, options?.charEncoding)}=` + : ""; + encValue = `${k}${encodeValue(pv)}`; + } + + out += encValue == null ? "" : `.${encValue}`; + }); + + return out; +} + +type FormEncoder = ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +) => string | undefined; + +function formEncoder(sep: string): FormEncoder { + return ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, + ) => { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + const encodedSep = encodeString(sep); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue: string | null | undefined = null; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(encodedSep); + } else if (isPlainObject(pv)) { + encValue = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `${encodeString(k)}${encodedSep}${encodeValue(v)}`; + })?.join(encodedSep); + } else { + encValue = `${encodeValue(pv)}`; + } + + if (encValue == null) { + return; + } + + tmp = `${encodeKeyChars(pk, options?.charEncoding)}=${encValue}`; + + // If we end up with the nothing then skip forward + if (!tmp || tmp === "=") { + return; + } + + out += `&${tmp}`; + }); + + return out.slice(1); + }; +} + +export const encodeForm = formEncoder(","); +export const encodeSpaceDelimited = formEncoder(" "); +export const encodePipeDelimited = formEncoder("|"); + +export function encodeBodyForm( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +): string { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = JSON.stringify(pv, jsonReplacer); + } else if (isPlainObject(pv)) { + encValue = JSON.stringify(pv, jsonReplacer); + } else { + encValue = `${encodeValue(pv)}`; + } + + tmp = `${encodeKeyChars(pk, options?.charEncoding)}=${encValue}`; + + // If we end up with the nothing then skip forward + if (!tmp || tmp === "=") { + return; + } + + out += `&${tmp}`; + }); + + return out.slice(1); +} + +export function encodeDeepObject( + key: string, + value: unknown, + options?: { charEncoding?: CharEncoding }, +): string | undefined { + if (value == null) { + return; + } + + if (!isPlainObject(value)) { + throw new EncodingError( + `Value of parameter '${key}' which uses deepObject encoding must be an object or null`, + ); + } + + return encodeDeepObjectObject(key, value, options); +} + +export function encodeDeepObjectObject( + key: string, + value: unknown, + options?: { charEncoding?: CharEncoding }, +): string | undefined { + if (value == null) { + return; + } + + let out = ""; + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + + if (!isPlainObject(value)) { + throw new EncodingError(`Expected parameter '${key}' to be an object.`); + } + + Object.entries(value).forEach(([ck, cv]) => { + if (cv == null) { + return; + } + + const pk = `${key}[${ck}]`; + + if (isPlainObject(cv)) { + const objOut = encodeDeepObjectObject(pk, cv, options); + + out += objOut == null ? "" : `&${objOut}`; + + return; + } + + const pairs: unknown[] = Array.isArray(cv) ? cv : [cv]; + const encoded = mapDefined(pairs, (v) => { + return `${encodeKeyChars(pk, options?.charEncoding)}=${ + encodeString(serializeValue(v)) + }`; + })?.join("&"); + + out += encoded == null ? "" : `&${encoded}`; + }); + + return out.slice(1); +} + +export function encodeJSON( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +): string | undefined { + if (typeof value === "undefined") { + return; + } + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + + const encVal = encodeString(JSON.stringify(value, jsonReplacer)); + + return options?.explode + ? encVal + : `${encodeKeyChars(key, options?.charEncoding)}=${encVal}`; +} + +export const encodeSimple = ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: CharEncoding }, +): string | undefined => { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return encodeChars(v, options?.charEncoding); + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp: string | null | undefined = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + tmp = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(","); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `,${encodeString(k)},${encodeValue(v)}`; + }); + tmp = mapped?.join("").slice(1); + } else { + const k = options?.explode && isPlainObject(value) ? `${pk}=` : ""; + tmp = `${k}${encodeValue(pv)}`; + } + + out += tmp ? `,${tmp}` : ""; + }); + + return out.slice(1); +}; + +function explode(key: string, value: unknown): [string, unknown][] { + if (Array.isArray(value)) { + return value.map((v) => [key, v]); + } else if (isPlainObject(value)) { + const o = value ?? {}; + return Object.entries(o).map(([k, v]) => [k, v]); + } else { + return [[key, value]]; + } +} + +function serializeValue(value: unknown): string { + if (value == null) { + return ""; + } else if (value instanceof Date) { + return value.toISOString(); + } else if (value instanceof Uint8Array) { + return bytesToBase64(value); + } else if (typeof value === "object") { + return JSON.stringify(value, jsonReplacer); + } + + return `${value}`; +} + +function jsonReplacer(_: string, value: unknown): unknown { + if (value instanceof Uint8Array) { + return bytesToBase64(value); + } else { + return value; + } +} + +function mapDefined(inp: T[], mapper: (v: T) => R): R[] | null { + const res = inp.reduce((acc, v) => { + if (v == null) { + return acc; + } + + const m = mapper(v); + if (m == null) { + return acc; + } + + acc.push(m); + + return acc; + }, []); + + return res.length ? res : null; +} + +function mapDefinedEntries( + inp: Iterable<[K, V]>, + mapper: (v: [K, V]) => R, +): R[] | null { + const acc: R[] = []; + for (const [k, v] of inp) { + if (v == null) { + continue; + } + + const m = mapper([k, v]); + if (m == null) { + continue; + } + + acc.push(m); + } + + return acc.length ? acc : null; +} + +export function queryJoin(...args: (string | undefined)[]): string { + return args.filter(Boolean).join("&"); +} + +type QueryEncoderOptions = { + explode?: boolean; + charEncoding?: CharEncoding; + allowEmptyValue?: string[]; +}; + +type QueryEncoder = ( + key: string, + value: unknown, + options?: QueryEncoderOptions, +) => string | undefined; + +type BulkQueryEncoder = ( + values: Record, + options?: QueryEncoderOptions, +) => string; + +export function queryEncoder(f: QueryEncoder): BulkQueryEncoder { + const bulkEncode = function( + values: Record, + options?: QueryEncoderOptions, + ): string { + const opts: QueryEncoderOptions = { + ...options, + explode: options?.explode ?? true, + charEncoding: options?.charEncoding ?? "percent", + }; + + const allowEmptySet = new Set(options?.allowEmptyValue ?? []); + + const encoded = Object.entries(values).map(([key, value]) => { + if (allowEmptySet.has(key)) { + if ( + value === undefined + || value === null + || value === "" + || (Array.isArray(value) && value.length === 0) + ) { + return `${encodeURIComponent(key)}=`; + } + } + return f(key, value, opts); + }); + return queryJoin(...encoded); + }; + + return bulkEncode; +} + +export const encodeJSONQuery = queryEncoder(encodeJSON); +export const encodeFormQuery = queryEncoder(encodeForm); +export const encodeSpaceDelimitedQuery = queryEncoder(encodeSpaceDelimited); +export const encodePipeDelimitedQuery = queryEncoder(encodePipeDelimited); +export const encodeDeepObjectQuery = queryEncoder(encodeDeepObject); + +function isBlobLike(val: unknown): val is Blob { + if (val instanceof Blob) { + return true; + } + + if (typeof val !== "object" || val == null || !(Symbol.toStringTag in val)) { + return false; + } + + const tag = val[Symbol.toStringTag]; + if (tag !== "Blob" && tag !== "File") { + return false; + } + + return "stream" in val && typeof val.stream === "function"; +} + +export function appendForm( + fd: FormData, + key: string, + value: unknown, + fileName?: string, +): void { + if (value == null) { + return; + } else if (isBlobLike(value)) { + if (fileName) { + fd.append(key, value as Blob, fileName); + } else { + fd.append(key, value as Blob); + } + } else { + fd.append(key, String(value)); + } +} + +export async function normalizeBlob( + value: Pick, +): Promise { + if (value instanceof Blob) { + return value; + } + return new Blob([await value.arrayBuffer()], { type: value.type }); +} diff --git a/client/admin/src/sdk/src/lib/env.ts b/client/admin/src/sdk/src/lib/env.ts new file mode 100644 index 00000000000..b909fba8ce9 --- /dev/null +++ b/client/admin/src/sdk/src/lib/env.ts @@ -0,0 +1,57 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export interface Env { + GRAM_DEBUG?: boolean | undefined; +} + +export const envSchema: z.ZodMiniType = z.object({ + GRAM_DEBUG: z.optional(z.coerce.boolean()), +}); + +/** + * Checks for the existence of the Deno global object to determine the environment. + * @returns {boolean} True if the runtime is Deno, false otherwise. + */ +function isDeno() { + if ("Deno" in globalThis) { + return true; + } + + return false; +} + +let envMemo: Env | undefined = undefined; +/** + * Reads and validates environment variables. + */ +export function env(): Env { + if (envMemo) { + return envMemo; + } + + const globals = globalThis as { + Deno?: { env?: { toObject?: () => Record } }; + process?: { env?: Record }; + }; + + let envObject: Record = {}; + if (isDeno()) { + envObject = globals.Deno?.env?.toObject?.() ?? {}; + } else { + envObject = globals.process?.env ?? {}; + } + + envMemo = envSchema.parse(envObject); + return envMemo; +} + +/** + * Clears the cached env object. Useful for testing with a fresh environment. + */ +export function resetEnv() { + envMemo = undefined; +} diff --git a/client/admin/src/sdk/src/lib/files.ts b/client/admin/src/sdk/src/lib/files.ts new file mode 100644 index 00000000000..6ca6b37d35a --- /dev/null +++ b/client/admin/src/sdk/src/lib/files.ts @@ -0,0 +1,104 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * Consumes a stream and returns a concatenated array buffer. Useful in + * situations where we need to read the whole file because it forms part of a + * larger payload containing other fields, and we can't modify the underlying + * request structure. + */ +export async function readableStreamToArrayBuffer( + readable: ReadableStream, +): Promise { + const reader = readable.getReader(); + const chunks: Uint8Array[] = []; + + let totalLength = 0; + let done = false; + + while (!done) { + const { value, done: doneReading } = await reader.read(); + + if (doneReading) { + done = true; + } else { + chunks.push(value); + totalLength += value.length; + } + } + + const concatenatedChunks = new Uint8Array(totalLength); + let offset = 0; + + for (const chunk of chunks) { + concatenatedChunks.set(chunk, offset); + offset += chunk.length; + } + + return concatenatedChunks.buffer as ArrayBuffer; +} + +/** + * Determines the MIME content type based on a file's extension. + * Returns null if the extension is not recognized. + */ +export function getContentTypeFromFileName(fileName: string): string | null { + if (!fileName) return null; + + const ext = fileName.toLowerCase().split(".").pop(); + if (!ext) return null; + + const mimeTypes: Record = { + json: "application/json", + xml: "application/xml", + html: "text/html", + htm: "text/html", + txt: "text/plain", + csv: "text/csv", + pdf: "application/pdf", + png: "image/png", + jpg: "image/jpeg", + jpeg: "image/jpeg", + gif: "image/gif", + svg: "image/svg+xml", + js: "application/javascript", + css: "text/css", + zip: "application/zip", + tar: "application/x-tar", + gz: "application/gzip", + mp4: "video/mp4", + mp3: "audio/mpeg", + wav: "audio/wav", + webp: "image/webp", + ico: "image/x-icon", + woff: "font/woff", + woff2: "font/woff2", + ttf: "font/ttf", + otf: "font/otf", + }; + + return mimeTypes[ext] || null; +} + +/** + * Creates a Blob from file content with the given MIME type. + * + * Node.js Buffers are Uint8Array subclasses that may share a pooled + * ArrayBuffer (byteOffset > 0, byteLength < buffer.byteLength). Passing + * such a Buffer directly to `new Blob([buf])` can include the entire + * underlying pool on some runtimes, producing a Blob with extra bytes + * that corrupts multipart uploads. + * + * Copying into a standalone Uint8Array ensures the Blob receives only the + * intended bytes regardless of runtime behaviour. + */ +export function bytesToBlob( + content: Uint8Array | ArrayBuffer | Blob | string, + contentType: string, +): Blob { + if (content instanceof Uint8Array) { + return new Blob([new Uint8Array(content)], { type: contentType }); + } + return new Blob([content as BlobPart], { type: contentType }); +} diff --git a/client/admin/src/sdk/src/lib/http.ts b/client/admin/src/sdk/src/lib/http.ts new file mode 100644 index 00000000000..6b7a6cf3e28 --- /dev/null +++ b/client/admin/src/sdk/src/lib/http.ts @@ -0,0 +1,325 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export type Fetcher = ( + input: RequestInfo | URL, + init?: RequestInit, +) => Promise; + +export type Awaitable = T | Promise; + +const DEFAULT_FETCHER: Fetcher = (input, init) => { + // If input is a Request and init is undefined, Bun will discard the method, + // headers, body and other options that were set on the request object. + // Node.js and browers would ignore an undefined init value. This check is + // therefore needed for interop with Bun. + if (init == null) { + return fetch(input); + } else { + return fetch(input, init); + } +}; + +export type RequestInput = { + /** + * The URL the request will use. + */ + url: URL; + /** + * Options used to create a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request). + */ + options?: RequestInit | undefined; +}; + +export interface HTTPClientOptions { + fetcher?: Fetcher; +} + +export type BeforeRequestHook = (req: Request) => Awaitable; +export type RequestErrorHook = (err: unknown, req: Request) => Awaitable; +export type ResponseHook = (res: Response, req: Request) => Awaitable; + +export class HTTPClient { + private fetcher: Fetcher; + private requestHooks: BeforeRequestHook[] = []; + private requestErrorHooks: RequestErrorHook[] = []; + private responseHooks: ResponseHook[] = []; + private options: HTTPClientOptions; + + constructor(options: HTTPClientOptions = {}) { + this.options = options; + this.fetcher = options.fetcher || DEFAULT_FETCHER; + } + + async request(request: Request): Promise { + let req = request; + for (const hook of this.requestHooks) { + const nextRequest = await hook(req); + if (nextRequest) { + req = nextRequest; + } + } + + try { + const res = await this.fetcher(req); + + for (const hook of this.responseHooks) { + await hook(res, req); + } + + return res; + } catch (err) { + for (const hook of this.requestErrorHooks) { + await hook(err, req); + } + + throw err; + } + } + + /** + * Registers a hook that is called before a request is made. The hook function + * can mutate the request or return a new request. This may be useful to add + * additional information to request such as request IDs and tracing headers. + */ + addHook(hook: "beforeRequest", fn: BeforeRequestHook): this; + /** + * Registers a hook that is called when a request cannot be made due to a + * network error. + */ + addHook(hook: "requestError", fn: RequestErrorHook): this; + /** + * Registers a hook that is called when a response has been received from the + * server. + */ + addHook(hook: "response", fn: ResponseHook): this; + addHook( + ...args: + | [hook: "beforeRequest", fn: BeforeRequestHook] + | [hook: "requestError", fn: RequestErrorHook] + | [hook: "response", fn: ResponseHook] + ) { + if (args[0] === "beforeRequest") { + this.requestHooks.push(args[1]); + } else if (args[0] === "requestError") { + this.requestErrorHooks.push(args[1]); + } else if (args[0] === "response") { + this.responseHooks.push(args[1]); + } else { + throw new Error(`Invalid hook type: ${args[0]}`); + } + return this; + } + + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "beforeRequest", fn: BeforeRequestHook): this; + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "requestError", fn: RequestErrorHook): this; + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "response", fn: ResponseHook): this; + removeHook( + ...args: + | [hook: "beforeRequest", fn: BeforeRequestHook] + | [hook: "requestError", fn: RequestErrorHook] + | [hook: "response", fn: ResponseHook] + ): this { + let target: unknown[]; + if (args[0] === "beforeRequest") { + target = this.requestHooks; + } else if (args[0] === "requestError") { + target = this.requestErrorHooks; + } else if (args[0] === "response") { + target = this.responseHooks; + } else { + throw new Error(`Invalid hook type: ${args[0]}`); + } + + const index = target.findIndex((v) => v === args[1]); + if (index >= 0) { + target.splice(index, 1); + } + + return this; + } + + clone(): HTTPClient { + const child = new HTTPClient(this.options); + child.requestHooks = this.requestHooks.slice(); + child.requestErrorHooks = this.requestErrorHooks.slice(); + child.responseHooks = this.responseHooks.slice(); + + return child; + } +} + +export type StatusCodePredicate = number | string | (number | string)[]; + +// A semicolon surrounded by optional whitespace characters is used to separate +// segments in a media type string. +const mediaParamSeparator = /\s*;\s*/g; + +export function matchContentType(response: Response, pattern: string): boolean { + // `*` is a special case which means anything is acceptable. + if (pattern === "*") { + return true; + } + + let contentType = + response.headers.get("content-type")?.trim() || "application/octet-stream"; + contentType = contentType.toLowerCase(); + + const wantParts = pattern.toLowerCase().trim().split(mediaParamSeparator); + const [wantType = "", ...wantParams] = wantParts; + + if (wantType.split("/").length !== 2) { + return false; + } + + const gotParts = contentType.split(mediaParamSeparator); + const [gotType = "", ...gotParams] = gotParts; + + const [type = "", subtype = ""] = gotType.split("/"); + if (!type || !subtype) { + return false; + } + + if ( + wantType !== "*/*" && + gotType !== wantType && + `${type}/*` !== wantType && + `*/${subtype}` !== wantType + ) { + return false; + } + + if (gotParams.length < wantParams.length) { + return false; + } + + const params = new Set(gotParams); + for (const wantParam of wantParams) { + if (!params.has(wantParam)) { + return false; + } + } + + return true; +} + +const codeRangeRE = new RegExp("^[0-9]xx$", "i"); + +export function matchStatusCode( + response: Response, + codes: StatusCodePredicate, +): boolean { + const actual = `${response.status}`; + const expectedCodes = Array.isArray(codes) ? codes : [codes]; + if (!expectedCodes.length) { + return false; + } + + return expectedCodes.some((ec) => { + const code = `${ec}`; + + if (code === "default") { + return true; + } + + if (!codeRangeRE.test(`${code}`)) { + return code === actual; + } + + const expectFamily = code.charAt(0); + if (!expectFamily) { + throw new Error("Invalid status code range"); + } + + const actualFamily = actual.charAt(0); + if (!actualFamily) { + throw new Error(`Invalid response status code: ${actual}`); + } + + return actualFamily === expectFamily; + }); +} + +export function matchResponse( + response: Response, + code: StatusCodePredicate, + contentTypePattern: string, +): boolean { + return ( + matchStatusCode(response, code) && + matchContentType(response, contentTypePattern) + ); +} + +/** + * Uses various heurisitics to determine if an error is a connection error. + */ +export function isConnectionError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Covers fetch in Deno as well + const isBrowserErr = + err instanceof TypeError && + err.message.toLowerCase().startsWith("failed to fetch"); + + const isNodeErr = + err instanceof TypeError && + err.message.toLowerCase().startsWith("fetch failed"); + + const isBunErr = "name" in err && err.name === "ConnectionError"; + + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnreset"; + + return isBrowserErr || isNodeErr || isGenericErr || isBunErr; +} + +/** + * Uses various heurisitics to determine if an error is a timeout error. + */ +export function isTimeoutError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Fetch in browser, Node.js, Bun, Deno + const isNative = "name" in err && err.name === "TimeoutError"; + const isLegacyNative = "code" in err && err.code === 23; + + // Node.js HTTP client and Axios + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnaborted"; + + return isNative || isLegacyNative || isGenericErr; +} + +/** + * Uses various heurisitics to determine if an error is a abort error. + */ +export function isAbortError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Fetch in browser, Node.js, Bun, Deno + const isNative = "name" in err && err.name === "AbortError"; + const isLegacyNative = "code" in err && err.code === 20; + + // Node.js HTTP client and Axios + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnaborted"; + + return isNative || isLegacyNative || isGenericErr; +} diff --git a/client/admin/src/sdk/src/lib/logger.ts b/client/admin/src/sdk/src/lib/logger.ts new file mode 100644 index 00000000000..d181f2937d4 --- /dev/null +++ b/client/admin/src/sdk/src/lib/logger.ts @@ -0,0 +1,9 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export interface Logger { + group(label?: string): void; + groupEnd(): void; + log(message: any, ...args: any[]): void; +} diff --git a/client/admin/src/sdk/src/lib/matchers.ts b/client/admin/src/sdk/src/lib/matchers.ts new file mode 100644 index 00000000000..efc0928ae61 --- /dev/null +++ b/client/admin/src/sdk/src/lib/matchers.ts @@ -0,0 +1,346 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { APIError } from "../models/errors/apierror.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { ERR, OK, Result } from "../types/fp.js"; +import { matchResponse, matchStatusCode, StatusCodePredicate } from "./http.js"; +import { isPlainObject } from "./primitives.js"; + +export type Encoding = + | "jsonl" + | "json" + | "text" + | "bytes" + | "stream" + | "sse" + | "nil" + | "fail"; + +const DEFAULT_CONTENT_TYPES: Record = { + jsonl: "application/jsonl", + json: "application/json", + text: "text/plain", + bytes: "application/octet-stream", + stream: "application/octet-stream", + sse: "text/event-stream", + nil: "*", + fail: "*", +}; + +type Schema = { parse(raw: unknown): T }; + +type MatchOptions = { + ctype?: string; + hdrs?: boolean; + key?: string; + sseSentinel?: string; +}; + +export type ValueMatcher = MatchOptions & { + enc: Encoding; + codes: StatusCodePredicate; + schema: Schema; +}; + +export type ErrorMatcher = MatchOptions & { + enc: Encoding; + codes: StatusCodePredicate; + schema: Schema; + err: true; +}; + +export type FailMatcher = { + enc: "fail"; + codes: StatusCodePredicate; +}; + +export type Matcher = ValueMatcher | ErrorMatcher | FailMatcher; + +export function jsonErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "json", codes, schema }; +} +export function json( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "json", codes, schema }; +} + +export function jsonl( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "jsonl", codes, schema }; +} + +export function jsonlErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "jsonl", codes, schema }; +} +export function textErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "text", codes, schema }; +} +export function text( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "text", codes, schema }; +} + +export function bytesErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "bytes", codes, schema }; +} +export function bytes( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "bytes", codes, schema }; +} + +export function streamErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "stream", codes, schema }; +} +export function stream( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "stream", codes, schema }; +} + +export function sseErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "sse", codes, schema }; +} +export function sse( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "sse", codes, schema }; +} + +export function nilErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "nil", codes, schema }; +} +export function nil( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "nil", codes, schema }; +} + +export function fail(codes: StatusCodePredicate): FailMatcher { + return { enc: "fail", codes }; +} + +export type MatchedValue = Matchers extends Matcher[] + ? T + : never; +export type MatchedError = Matchers extends Matcher[] + ? E + : never; +export type MatchFunc = ( + response: Response, + request: Request, + options?: { resultKey?: string; extraFields?: Record }, +) => Promise<[result: Result, raw: unknown]>; + +export function match( + ...matchers: Array> +): MatchFunc { + return async function matchFunc( + response: Response, + request: Request, + options?: { resultKey?: string; extraFields?: Record }, + ): Promise< + [result: Result, raw: unknown] + > { + let raw: unknown; + let matcher: Matcher | undefined; + for (const match of matchers) { + const { codes } = match; + const ctpattern = "ctype" in match + ? match.ctype + : DEFAULT_CONTENT_TYPES[match.enc]; + if (ctpattern && matchResponse(response, codes, ctpattern)) { + matcher = match; + break; + } else if (!ctpattern && matchStatusCode(response, codes)) { + matcher = match; + break; + } + } + + if (!matcher) { + return [{ + ok: false, + error: new APIError("Unexpected Status or Content-Type", { + response, + request, + body: await response.text().catch(() => ""), + }), + }, raw]; + } + + const encoding = matcher.enc; + let body = ""; + switch (encoding) { + case "json": + body = await response.text(); + raw = JSON.parse(body); + break; + case "jsonl": + raw = response.body; + break; + case "bytes": + raw = new Uint8Array(await response.arrayBuffer()); + break; + case "stream": + raw = response.body; + break; + case "text": + body = await response.text(); + raw = body; + break; + case "sse": + raw = response.body; + break; + case "nil": + body = await response.text(); + raw = undefined; + break; + case "fail": + body = await response.text(); + raw = body; + break; + default: + throw new Error( + `Unsupported response type: ${encoding satisfies never}`, + ); + } + + if (matcher.enc === "fail") { + return [{ + ok: false, + error: new APIError("API error occurred", { request, response, body }), + }, raw]; + } + + const resultKey = matcher.key || options?.resultKey; + let data: unknown; + + if ("err" in matcher) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + ...(isPlainObject(raw) ? raw : null), + request$: request, + response$: response, + body$: body, + }; + } else if (resultKey) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + [resultKey]: raw, + }; + } else if (matcher.hdrs) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + ...(isPlainObject(raw) ? raw : null), + }; + } else { + data = raw; + } + + if ("err" in matcher) { + const result = safeParseResponse( + data, + (v: unknown) => matcher.schema.parse(v), + "Response validation failed", + { request, response, body }, + ); + return [result.ok ? { ok: false, error: result.value } : result, raw]; + } else { + return [ + safeParseResponse( + data, + (v: unknown) => matcher.schema.parse(v), + "Response validation failed", + { request, response, body }, + ), + raw, + ]; + } + }; +} + +const headerValRE = /, */; +/** + * Iterates over a Headers object and returns an object with all the header + * entries. Values are represented as an array to account for repeated headers. + */ +export function unpackHeaders(headers: Headers): Record { + const out: Record = {}; + + for (const [k, v] of headers.entries()) { + out[k] = v.split(headerValRE); + } + + return out; +} + +function safeParseResponse( + rawValue: Inp, + fn: (value: Inp) => Out, + errorMessage: string, + httpMeta: { response: Response; request: Request; body: string }, +): Result { + try { + return OK(fn(rawValue)); + } catch (err) { + return ERR( + new ResponseValidationError(errorMessage, { + cause: err, + rawValue, + rawMessage: errorMessage, + ...httpMeta, + }), + ); + } +} diff --git a/client/admin/src/sdk/src/lib/primitives.ts b/client/admin/src/sdk/src/lib/primitives.ts new file mode 100644 index 00000000000..8ce65db0f7c --- /dev/null +++ b/client/admin/src/sdk/src/lib/primitives.ts @@ -0,0 +1,166 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +class InvariantError extends Error { + constructor(message: string) { + super(message); + this.name = "InvariantError"; + } +} + +export function invariant( + condition: unknown, + message: string, +): asserts condition { + if (!condition) { + throw new InvariantError(message); + } +} + +export type ExactPartial = { + [P in keyof T]?: T[P] | undefined; +}; + +export type Remap = { + [k in keyof Inp as Mapping[k] extends string /* if we have a string mapping for this key then use it */ + ? Mapping[k] + : Mapping[k] extends null /* if the mapping is to `null` then drop the key */ + ? never + : k /* otherwise keep the key as-is */]: Inp[k]; +}; + +/** + * Converts or omits an object's keys according to a mapping. + * + * @param inp An object whose keys will be remapped + * @param mappings A mapping of original keys to new keys. If a key is not present in the mapping, it will be left as is. If a key is mapped to `null`, it will be removed in the resulting object. + * @returns A new object with keys remapped or omitted according to the mappings + */ +export function remap< + Inp extends Record, + const Mapping extends { [k in keyof Inp]?: string | null }, +>(inp: Inp, mappings: Mapping): Remap { + let out: any = {}; + + if (!Object.keys(mappings).length) { + out = inp; + return out; + } + + for (const [k, v] of Object.entries(inp)) { + const j = mappings[k]; + if (j === null) { + continue; + } + out[j ?? k] = v; + } + + return out; +} + +export function combineSignals( + ...signals: Array +): AbortSignal | null { + const filtered: AbortSignal[] = []; + for (const signal of signals) { + if (signal) { + filtered.push(signal); + } + } + + switch (filtered.length) { + case 0: + case 1: + return filtered[0] || null; + default: + if ("any" in AbortSignal && typeof AbortSignal.any === "function") { + return AbortSignal.any(filtered); + } + return abortSignalAny(filtered); + } +} + +export function abortSignalAny(signals: AbortSignal[]): AbortSignal { + const controller = new AbortController(); + const result = controller.signal; + if (!signals.length) { + return controller.signal; + } + + if (signals.length === 1) { + return signals[0] || controller.signal; + } + + for (const signal of signals) { + if (signal.aborted) { + return signal; + } + } + + function abort(this: AbortSignal) { + controller.abort(this.reason); + clean(); + } + + const signalRefs: WeakRef[] = []; + function clean() { + for (const signalRef of signalRefs) { + const signal = signalRef.deref(); + if (signal) { + signal.removeEventListener("abort", abort); + } + } + } + + for (const signal of signals) { + signalRefs.push(new WeakRef(signal)); + signal.addEventListener("abort", abort); + } + + return result; +} + +export function compactMap( + values: Record, +): Record { + const out: Record = {}; + + for (const [k, v] of Object.entries(values)) { + if (typeof v !== "undefined") { + out[k] = v; + } + } + + return out; +} + +export function allRequired>( + v: V, +): + | { + [K in keyof V]: NonNullable; + } + | undefined { + if (Object.values(v).every((x) => x == null)) { + return void 0; + } + + return v as ReturnType>; +} + +export function isPlainObject( + value: unknown, +): value is Record { + if (value === null || typeof value !== "object") return false; + if (Object.prototype.toString.call(value) !== "[object Object]") return false; + const proto = Object.getPrototypeOf(value); + if (proto === null || proto === Object.prototype) return true; + // cross-realm plain objects (vm contexts, iframes) inherit from a + // different realm's Object.prototype, which itself has a null prototype + try { + return Object.getPrototypeOf(proto) === null; + } catch { + return false; + } +} diff --git a/client/admin/src/sdk/src/lib/retries.ts b/client/admin/src/sdk/src/lib/retries.ts new file mode 100644 index 00000000000..21a647e1e9a --- /dev/null +++ b/client/admin/src/sdk/src/lib/retries.ts @@ -0,0 +1,226 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { isConnectionError, isTimeoutError } from "./http.js"; + +export type BackoffStrategy = { + initialInterval: number; + maxInterval: number; + exponent: number; + maxElapsedTime: number; +}; + +const defaultBackoff: BackoffStrategy = { + initialInterval: 500, + maxInterval: 60000, + exponent: 1.5, + maxElapsedTime: 3600000, +}; + +export type RetryConfig = + | { strategy: "none" } + | { + strategy: "backoff"; + backoff?: BackoffStrategy; + retryConnectionErrors?: boolean; + }; + +/** + * PermanentError is an error that is not recoverable. Throwing this error will + * cause a retry loop to terminate. + */ +export class PermanentError extends Error { + /** The underlying cause of the error. */ + override readonly cause: unknown; + + constructor(message: string, options?: { cause?: unknown }) { + let msg = message; + if (options?.cause) { + msg += `: ${options.cause}`; + } + + super(msg, options); + this.name = "PermanentError"; + // In older runtimes, the cause field would not have been assigned through + // the super() call. + if (typeof this.cause === "undefined") { + this.cause = options?.cause; + } + + Object.setPrototypeOf(this, PermanentError.prototype); + } +} + +/** + * TemporaryError is an error is used to signal that an HTTP request can be + * retried as part of a retry loop. If retry attempts are exhausted and this + * error is thrown, the response will be returned to the caller. + */ +export class TemporaryError extends Error { + response: Response; + + constructor(message: string, response: Response) { + super(message); + this.response = response; + this.name = "TemporaryError"; + + Object.setPrototypeOf(this, TemporaryError.prototype); + } +} + +export async function retry( + fetchFn: () => Promise, + options: { + config: RetryConfig; + statusCodes: string[]; + }, +): Promise { + switch (options.config.strategy) { + case "backoff": + return retryBackoff( + wrapFetcher(fetchFn, { + statusCodes: options.statusCodes, + retryConnectionErrors: !!options.config.retryConnectionErrors, + }), + options.config.backoff ?? defaultBackoff, + ); + default: + return await fetchFn(); + } +} + +function wrapFetcher( + fn: () => Promise, + options: { + statusCodes: string[]; + retryConnectionErrors: boolean; + }, +): () => Promise { + return async () => { + try { + const res = await fn(); + if (isRetryableResponse(res, options.statusCodes)) { + throw new TemporaryError( + "Response failed with retryable status code", + res, + ); + } + + return res; + } catch (err: unknown) { + if (err instanceof TemporaryError) { + throw err; + } + + if ( + options.retryConnectionErrors && + (isTimeoutError(err) || isConnectionError(err)) + ) { + throw err; + } + + throw new PermanentError("Permanent error", { cause: err }); + } + }; +} + +const codeRangeRE = new RegExp("^[0-9]xx$", "i"); + +function isRetryableResponse(res: Response, statusCodes: string[]): boolean { + const actual = `${res.status}`; + + return statusCodes.some((code) => { + if (!codeRangeRE.test(code)) { + return code === actual; + } + + const expectFamily = code.charAt(0); + if (!expectFamily) { + throw new Error("Invalid status code range"); + } + + const actualFamily = actual.charAt(0); + if (!actualFamily) { + throw new Error(`Invalid response status code: ${actual}`); + } + + return actualFamily === expectFamily; + }); +} + +async function retryBackoff( + fn: () => Promise, + strategy: BackoffStrategy, +): Promise { + const { maxElapsedTime, initialInterval, exponent, maxInterval } = strategy; + + const start = Date.now(); + let x = 0; + + while (true) { + try { + const res = await fn(); + return res; + } catch (err: unknown) { + if (err instanceof PermanentError) { + throw err.cause; + } + const elapsed = Date.now() - start; + if (elapsed > maxElapsedTime) { + if (err instanceof TemporaryError) { + return err.response; + } + + throw err; + } + + let retryInterval = 0; + if (err instanceof TemporaryError) { + retryInterval = retryIntervalFromResponse(err.response); + } + + if (retryInterval <= 0) { + retryInterval = + initialInterval * Math.pow(x, exponent) + Math.random() * 1000; + } + + const d = Math.min(retryInterval, maxInterval); + + await delay(d); + x++; + } + } +} + +function retryIntervalFromResponse(res: Response): number { + const retryAfterMsVal = res.headers.get("retry-after-ms"); + if (retryAfterMsVal) { + const parsedMs = Number(retryAfterMsVal); + if (Number.isFinite(parsedMs) && parsedMs >= 0) { + return parsedMs; + } + } + + const retryVal = res.headers.get("retry-after") || ""; + if (!retryVal) { + return 0; + } + + const parsedNumber = Number(retryVal); + if (Number.isInteger(parsedNumber)) { + return parsedNumber * 1000; + } + + const parsedDate = Date.parse(retryVal); + if (Number.isInteger(parsedDate)) { + const deltaMS = parsedDate - Date.now(); + return deltaMS > 0 ? Math.ceil(deltaMS) : 0; + } + + return 0; +} + +async function delay(delay: number): Promise { + return new Promise((resolve) => setTimeout(resolve, delay)); +} diff --git a/client/admin/src/sdk/src/lib/schemas.ts b/client/admin/src/sdk/src/lib/schemas.ts new file mode 100644 index 00000000000..61d7649b3d8 --- /dev/null +++ b/client/admin/src/sdk/src/lib/schemas.ts @@ -0,0 +1,94 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ERR, OK, Result } from "../types/fp.js"; + +/** + * Utility function that executes some code which may throw a ZodError. It + * intercepts this error and converts it to an SDKValidationError so as to not + * leak Zod implementation details to user code. + */ +export function parse( + rawValue: Inp, + fn: (value: Inp) => Out, + errorMessage: string, +): Out { + try { + return fn(rawValue); + } catch (err) { + if (err instanceof z.core.$ZodError) { + throw new SDKValidationError(errorMessage, err, rawValue); + } + throw err; + } +} + +/** + * Utility function that executes some code which may result in a ZodError. It + * intercepts this error and converts it to an SDKValidationError so as to not + * leak Zod implementation details to user code. + */ +export function safeParse( + rawValue: Inp, + fn: (value: Inp) => Out, + errorMessage: string, +): Result { + try { + return OK(fn(rawValue)); + } catch (err) { + return ERR(new SDKValidationError(errorMessage, err, rawValue)); + } +} + +export function collectExtraKeys< + Shape extends z.core.$ZodShape, + Catchall extends z.ZodMiniType, + K extends string, + Optional extends boolean, +>( + obj: z.ZodMiniObject>, + extrasKey: K, + optional: Optional, +): z.ZodMiniPipe< + z.ZodMiniObject>, + z.ZodMiniTransform< + & z.output> + & (Optional extends false ? { + [k in K]: Record>; + } + : { + [k in K]?: Record> | undefined; + }), + z.output>> + > +> { + return z.pipe( + obj, + z.transform((val: any) => { + const extras: Record> = {}; + const { shape } = obj; + for (const [key] of Object.entries(val)) { + if (key in shape) { + continue; + } + + const v = val[key]; + if (typeof v === "undefined") { + continue; + } + + extras[key] = v; + delete val[key]; + } + + if (optional && Object.keys(extras).length === 0) { + return val; + } + + return { ...val, [extrasKey]: extras }; + }), + ); +} diff --git a/client/admin/src/sdk/src/lib/sdks.ts b/client/admin/src/sdk/src/lib/sdks.ts new file mode 100644 index 00000000000..40ecf27da34 --- /dev/null +++ b/client/admin/src/sdk/src/lib/sdks.ts @@ -0,0 +1,442 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SDKHooks } from "../hooks/hooks.js"; +import { HookContext } from "../hooks/types.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ERR, OK, Result } from "../types/fp.js"; +import { stringToBase64 } from "./base64.js"; +import { SDK_METADATA, SDKOptions, serverURLFromOptions } from "./config.js"; +import { encodeForm } from "./encodings.js"; +import { env } from "./env.js"; +import { + HTTPClient, + isAbortError, + isConnectionError, + isTimeoutError, + matchContentType, +} from "./http.js"; +import { Logger } from "./logger.js"; +import { combineSignals } from "./primitives.js"; +import { retry, RetryConfig } from "./retries.js"; +import { SecurityState } from "./security.js"; + +export type RequestOptions = { + /** + * Sets a timeout, in milliseconds, on HTTP requests made by an SDK method. If + * `fetchOptions.signal` is set then it will take precedence over this option. + */ + timeoutMs?: number; + /** + * Set or override a retry policy on HTTP calls. + */ + retries?: RetryConfig; + /** + * Specifies the status codes which should be retried using the given retry policy. + */ + retryCodes?: string[]; + /** + * Overrides the base server URL that will be used by an operation. + */ + serverURL?: string | URL; + /** + * @deprecated `fetchOptions` has been flattened into `RequestOptions`. + * + * Sets various request options on the `fetch` call made by an SDK method. + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options|Request} + */ + fetchOptions?: Omit; +} & Omit; + +type RequestConfig = { + method: string; + path: string; + baseURL?: string | URL | undefined; + query?: string; + body?: RequestInit["body"]; + headers?: HeadersInit; + security?: SecurityState | null; + uaHeader?: string; + userAgent?: string | undefined; + timeoutMs?: number; +}; + +const gt: unknown = typeof globalThis === "undefined" ? null : globalThis; +const webWorkerLike = typeof gt === "object" + && gt != null + && "importScripts" in gt + && typeof gt["importScripts"] === "function"; +const isBrowserLike = webWorkerLike + || (typeof navigator !== "undefined" && "serviceWorker" in navigator) + || (typeof window === "object" && typeof window.document !== "undefined"); + +export class ClientSDK { + readonly #httpClient: HTTPClient; + readonly #hooks: SDKHooks; + readonly #logger?: Logger | undefined; + public readonly _baseURL: URL | null; + public readonly _options: SDKOptions & { hooks?: SDKHooks }; + + constructor(options: SDKOptions) { + const opt = options as unknown; + if ( + typeof opt === "object" + && opt != null + && "hooks" in opt + && opt.hooks instanceof SDKHooks + ) { + this.#hooks = opt.hooks; + } else { + this.#hooks = new SDKHooks(); + } + const defaultHttpClient = new HTTPClient(); + options.httpClient = options.httpClient || defaultHttpClient; + options = this.#hooks.sdkInit(options); + + const url = serverURLFromOptions(options); + if (url) { + url.pathname = url.pathname.replace(/\/+$/, "") + "/"; + } + this._baseURL = url; + this.#httpClient = options.httpClient || defaultHttpClient; + + this._options = { ...options, hooks: this.#hooks }; + + this.#logger = this._options.debugLogger; + if (!this.#logger && env().GRAM_DEBUG) { + this.#logger = console; + } + } + + public _createRequest( + context: HookContext, + conf: RequestConfig, + options?: RequestOptions, + ): Result { + const { method, path, query, headers: opHeaders, security } = conf; + + const base = conf.baseURL ?? this._baseURL; + if (!base) { + return ERR(new InvalidRequestError("No base URL provided for operation")); + } + const baseURL = new URL(base); + let reqURL: URL; + if (path) { + baseURL.pathname = baseURL.pathname.replace(/\/+$/, "") + "/"; + reqURL = new URL(path, baseURL); + if (!reqURL.search && baseURL.search) { + reqURL.search = baseURL.search; + } + } else { + reqURL = baseURL; + } + reqURL.hash = ""; + + // Appends already-encoded query pairs to a query string, replacing any + // existing pairs with the same key so later sources take precedence. + const mergeQuery = (current: string, additions: string): string => { + if (!additions) { + return current; + } + const additionKeys = new Set( + additions + .split("&") + .filter((pair) => pair !== "") + .map((pair) => pair.split("=")[0] ?? ""), + ); + const kept = current.split("&").filter((pair) => { + return pair !== "" && !additionKeys.has(pair.split("=")[0] ?? ""); + }); + return [...kept, additions].join("&"); + }; + + const encodeQueryRecord = (record: Record): string => { + return Object.entries(record) + .map(([k, v]) => { + if (v == null) { + return undefined; + } + const value = v; + return encodeForm(k, value, { + explode: Array.isArray(value), + charEncoding: "percent", + }); + }) + .filter((pair): pair is string => typeof pair !== "undefined") + .join("&"); + }; + + const finalQuery = [ + query || "", + encodeQueryRecord(security?.queryParams || {}), + ].reduce(mergeQuery, reqURL.search.slice(1)); + + if (finalQuery) { + reqURL.search = `?${finalQuery}`; + } + + const headers = new Headers(opHeaders); + + const username = security?.basic.username; + const password = security?.basic.password; + if (username != null || password != null) { + const encoded = stringToBase64( + [username || "", password || ""].join(":"), + ); + headers.set("Authorization", `Basic ${encoded}`); + } + + const securityHeaders = new Headers(security?.headers || {}); + for (const [k, v] of securityHeaders) { + headers.set(k, v); + } + + let cookie = headers.get("cookie") || ""; + for (const [k, v] of Object.entries(security?.cookies || {})) { + cookie += `; ${k}=${v}`; + } + cookie = cookie.startsWith("; ") ? cookie.slice(2) : cookie; + headers.set("cookie", cookie); + + const userHeaders = new Headers( + options?.headers ?? options?.fetchOptions?.headers, + ); + for (const [k, v] of userHeaders) { + headers.set(k, v); + } + + // Only set user agent header in non-browser-like environments since CORS + // policy disallows setting it in browsers e.g. Chrome throws an error. + if (!isBrowserLike) { + headers.set( + conf.uaHeader ?? "user-agent", + conf.userAgent ?? SDK_METADATA.userAgent, + ); + } + + const fetchOptions: Omit = { + ...options?.fetchOptions, + ...options, + }; + if (!fetchOptions?.signal && conf.timeoutMs != null && conf.timeoutMs > 0) { + context.timeoutMs = conf.timeoutMs; + } + + if (conf.body instanceof ReadableStream) { + Object.assign(fetchOptions, { duplex: "half" }); + } + + let input; + try { + input = this.#hooks.beforeCreateRequest(context, { + url: reqURL, + options: { + ...fetchOptions, + body: conf.body ?? null, + headers, + method, + }, + }); + } catch (err: unknown) { + return ERR( + new UnexpectedClientError("Create request hook failed to execute", { + cause: err, + }), + ); + } + + return OK(new Request(input.url, input.options)); + } + + public async _do( + request: Request, + options: { + context: HookContext; + isErrorStatusCode: (statusCode: number) => boolean; + retryConfig: RetryConfig; + retryCodes: string[]; + }, + ): Promise< + Result< + Response, + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + | UnexpectedClientError + > + > { + const { context, isErrorStatusCode } = options; + const timeoutMs = context.timeoutMs; + + return retry( + async () => { + const cloned = request.clone(); + let attempt = cloned; + if (timeoutMs != null && timeoutMs > 0) { + const timeoutSignal = AbortSignal.timeout(timeoutMs); + const combined = combineSignals(cloned.signal, timeoutSignal) + ?? timeoutSignal; + attempt = new Request(cloned, { signal: combined }); + } + const req = await this.#hooks.beforeRequest(context, attempt); + await logRequest(this.#logger, req).catch((e) => + this.#logger?.log("Failed to log request:", e) + ); + + let response = await this.#httpClient.request(req); + + try { + if (isErrorStatusCode(response.status)) { + const result = await this.#hooks.afterError( + context, + response, + null, + ); + if (result.error) { + throw result.error; + } + response = result.response || response; + } else { + response = await this.#hooks.afterSuccess(context, response); + } + } finally { + await logResponse(this.#logger, response, req) + .catch(e => this.#logger?.log("Failed to log response:", e)); + } + + return response; + }, + { config: options.retryConfig, statusCodes: options.retryCodes }, + ).then( + (r) => OK(r), + (err) => { + switch (true) { + case isAbortError(err): + return ERR( + new RequestAbortedError("Request aborted by client", { + cause: err, + }), + ); + case isTimeoutError(err): + return ERR( + new RequestTimeoutError("Request timed out", { cause: err }), + ); + case isConnectionError(err): + return ERR( + new ConnectionError("Unable to make request", { cause: err }), + ); + default: + return ERR( + new UnexpectedClientError("Unexpected HTTP client error", { + cause: err, + }), + ); + } + }, + ); + } +} + +const jsonLikeContentTypeRE = /^(application|text)\/([^+]+\+)*json.*/; +const jsonlLikeContentTypeRE = + /^(application|text)\/([^+]+\+)*(jsonl|x-ndjson)\b.*/; +async function logRequest(logger: Logger | undefined, req: Request) { + if (!logger) { + return; + } + + const contentType = req.headers.get("content-type"); + const ct = contentType?.split(";")[0] || ""; + + logger.group(`> Request: ${req.method} ${req.url}`); + + logger.group("Headers:"); + for (const [k, v] of req.headers.entries()) { + logger.log(`${k}: ${v}`); + } + logger.groupEnd(); + + logger.group("Body:"); + switch (true) { + case jsonLikeContentTypeRE.test(ct): + logger.log(await req.clone().json()); + break; + case ct.startsWith("text/"): + logger.log(await req.clone().text()); + break; + case ct === "multipart/form-data": { + const body = await req.clone().formData(); + for (const [k, v] of body) { + const vlabel = v instanceof Blob ? "" : v; + logger.log(`${k}: ${vlabel}`); + } + break; + } + default: + logger.log(`<${contentType}>`); + break; + } + logger.groupEnd(); + + logger.groupEnd(); +} + +async function logResponse( + logger: Logger | undefined, + res: Response, + req: Request, +) { + if (!logger) { + return; + } + + const contentType = res.headers.get("content-type"); + const ct = contentType?.split(";")[0] || ""; + + logger.group(`< Response: ${req.method} ${req.url}`); + logger.log("Status Code:", res.status, res.statusText); + + logger.group("Headers:"); + for (const [k, v] of res.headers.entries()) { + logger.log(`${k}: ${v}`); + } + logger.groupEnd(); + + logger.group("Body:"); + switch (true) { + case matchContentType(res, "application/json") + || jsonLikeContentTypeRE.test(ct) && !jsonlLikeContentTypeRE.test(ct): + logger.log(await res.clone().json()); + break; + case matchContentType(res, "application/jsonl") + || jsonlLikeContentTypeRE.test(ct): + case matchContentType(res, "text/event-stream"): + logger.log(`<${contentType}>`); + break; + case matchContentType(res, "text/*"): + logger.log(await res.clone().text()); + break; + case matchContentType(res, "multipart/form-data"): { + const body = await res.clone().formData(); + for (const [k, v] of body) { + const vlabel = v instanceof Blob ? "" : v; + logger.log(`${k}: ${vlabel}`); + } + break; + } + default: + logger.log(`<${contentType}>`); + break; + } + logger.groupEnd(); + + logger.groupEnd(); +} diff --git a/client/admin/src/sdk/src/lib/security.ts b/client/admin/src/sdk/src/lib/security.ts new file mode 100644 index 00000000000..7850aeab643 --- /dev/null +++ b/client/admin/src/sdk/src/lib/security.ts @@ -0,0 +1,241 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +type OAuth2PasswordFlow = { + username: string; + password: string; + clientID?: string | undefined; + clientSecret?: string | undefined; + tokenURL: string; +}; + +export const SecurityErrorCode = { + Incomplete: "incomplete", + UnrecognisedSecurityType: "unrecognized_security_type", +} as const; +export type SecurityErrorCode = + (typeof SecurityErrorCode)[keyof typeof SecurityErrorCode]; + +export class SecurityError extends Error { + public code: SecurityErrorCode; + + constructor( + code: SecurityErrorCode, + message: string, + ) { + super(message); + this.code = code; + this.name = "SecurityError"; + } + + static incomplete(): SecurityError { + return new SecurityError( + SecurityErrorCode.Incomplete, + "Security requirements not met in order to perform the operation", + ); + } + static unrecognizedType(type: string): SecurityError { + return new SecurityError( + SecurityErrorCode.UnrecognisedSecurityType, + `Unrecognised security type: ${type}`, + ); + } +} + +export type SecurityState = { + basic: { username?: string | undefined; password?: string | undefined }; + headers: Record; + queryParams: Record; + cookies: Record; + oauth2: ({ type: "password" } & OAuth2PasswordFlow) | { type: "none" }; +}; + +type SecurityInputBasic = { + type: "http:basic"; + value: + | { username?: string | undefined; password?: string | undefined } + | null + | undefined; +}; + +type SecurityInputBearer = { + type: "http:bearer"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputAPIKey = { + type: "apiKey:header" | "apiKey:query" | "apiKey:cookie"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOIDC = { + type: "openIdConnect"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOAuth2 = { + type: "oauth2"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOAuth2ClientCredentials = { + type: "oauth2:client_credentials"; + value: + | { + clientID?: string | undefined; + clientSecret?: string | undefined; + } + | null + | string + | undefined; + fieldName?: string; +}; + +type SecurityInputOAuth2PasswordCredentials = { + type: "oauth2:password"; + value: + | string + | null + | undefined; + fieldName?: string; +}; + +type SecurityInputCustom = { + type: "http:custom"; + value: any | null | undefined; + fieldName?: string; +}; + +export type SecurityInput = + | SecurityInputBasic + | SecurityInputBearer + | SecurityInputAPIKey + | SecurityInputOAuth2 + | SecurityInputOAuth2ClientCredentials + | SecurityInputOAuth2PasswordCredentials + | SecurityInputOIDC + | SecurityInputCustom; + +export function resolveSecurity( + ...options: SecurityInput[][] +): SecurityState | null { + const state: SecurityState = { + basic: {}, + headers: {}, + queryParams: {}, + cookies: {}, + oauth2: { type: "none" }, + }; + + const option = options.find((opts) => { + return opts.every((o) => { + if (o.value == null) { + return false; + } else if (o.type === "http:basic") { + return o.value.username != null || o.value.password != null; + } else if (o.type === "http:custom") { + return null; + } else if (o.type === "oauth2:password") { + return ( + typeof o.value === "string" && !!o.value + ); + } else if (o.type === "oauth2:client_credentials") { + if (typeof o.value == "string") { + return !!o.value; + } + return o.value.clientID != null || o.value.clientSecret != null; + } else if (typeof o.value === "string") { + return !!o.value; + } else { + throw new Error( + `Unrecognized security type: ${o.type} (value type: ${typeof o + .value})`, + ); + } + }); + }); + if (option == null) { + return null; + } + + option.forEach((spec) => { + if (spec.value == null) { + return; + } + + const { type } = spec; + + switch (type) { + case "apiKey:header": + state.headers[spec.fieldName] = spec.value; + break; + case "apiKey:query": + state.queryParams[spec.fieldName] = spec.value; + break; + case "apiKey:cookie": + state.cookies[spec.fieldName] = spec.value; + break; + case "http:basic": + applyBasic(state, spec); + break; + case "http:custom": + break; + case "http:bearer": + applyBearer(state, spec); + break; + case "oauth2": + applyBearer(state, spec); + break; + case "oauth2:password": + applyBearer(state, spec); + break; + case "oauth2:client_credentials": + break; + case "openIdConnect": + applyBearer(state, spec); + break; + default: + throw SecurityError.unrecognizedType((spec satisfies never, type)); + } + }); + + return state; +} + +function applyBasic( + state: SecurityState, + spec: SecurityInputBasic, +) { + if (spec.value == null) { + return; + } + + state.basic = spec.value; +} + +function applyBearer( + state: SecurityState, + spec: + | SecurityInputBearer + | SecurityInputOAuth2 + | SecurityInputOIDC + | SecurityInputOAuth2PasswordCredentials, +) { + if (typeof spec.value !== "string" || !spec.value) { + return; + } + + let value = spec.value; + if (value.slice(0, 7).toLowerCase() !== "bearer ") { + value = `Bearer ${value}`; + } + + if (spec.fieldName !== undefined) { + state.headers[spec.fieldName] = value; + } +} diff --git a/client/admin/src/sdk/src/lib/url.ts b/client/admin/src/sdk/src/lib/url.ts new file mode 100644 index 00000000000..79e7ce660b3 --- /dev/null +++ b/client/admin/src/sdk/src/lib/url.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +const hasOwn = Object.prototype.hasOwnProperty; + +export type Params = Partial>; + +export function pathToFunc( + pathPattern: string, + options?: { charEncoding?: "percent" | "none" }, +): (params?: Params) => string { + const paramRE = /\{([a-zA-Z0-9_][a-zA-Z0-9_-]*?)\}/g; + + return function buildURLPath(params: Record = {}): string { + return pathPattern + .replace(paramRE, function (_, placeholder) { + if (!hasOwn.call(params, placeholder)) { + throw new Error(`Parameter '${placeholder}' is required`); + } + + const value = params[placeholder]; + if (typeof value !== "string" && typeof value !== "number") { + throw new Error( + `Parameter '${placeholder}' must be a string or number`, + ); + } + + return options?.charEncoding === "percent" + ? encodeURIComponent(`${value}`) + : `${value}`; + }) + .replace(/^\/+/, ""); + }; +} diff --git a/client/admin/src/sdk/src/models/components/adminbulkupdateaccounttyperesult.ts b/client/admin/src/sdk/src/models/components/adminbulkupdateaccounttyperesult.ts new file mode 100644 index 00000000000..2feacd90f2e --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminbulkupdateaccounttyperesult.ts @@ -0,0 +1,50 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Outcome of a bulk account type change. + */ +export type AdminBulkUpdateAccountTypeResult = { + /** + * IDs from the request that matched no organization, deduplicated and in request order. Nothing was written for these. + */ + missingIds: Array; + /** + * IDs of the organizations whose account type was set. Order is unspecified: do not rely on it. + */ + updatedIds: Array; +}; + +/** @internal */ +export const AdminBulkUpdateAccountTypeResult$inboundSchema: z.ZodMiniType< + AdminBulkUpdateAccountTypeResult, + unknown +> = z.pipe( + z.object({ + missing_ids: z.array(z.string()), + updated_ids: z.array(z.string()), + }), + z.transform((v) => { + return remap$(v, { + "missing_ids": "missingIds", + "updated_ids": "updatedIds", + }); + }), +); + +export function adminBulkUpdateAccountTypeResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminBulkUpdateAccountTypeResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminBulkUpdateAccountTypeResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminchatanalysissettings.ts b/client/admin/src/sdk/src/models/components/adminchatanalysissettings.ts new file mode 100644 index 00000000000..58d82f7cd20 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminchatanalysissettings.ts @@ -0,0 +1,53 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminChatAnalysisSettings = { + businessMemoryDailyCap: number; + businessMemoryEnabled: boolean; + isDefault: boolean; + organizationId: string; + workUnitsDailyCap: number; + workUnitsEnabled: boolean; +}; + +/** @internal */ +export const AdminChatAnalysisSettings$inboundSchema: z.ZodMiniType< + AdminChatAnalysisSettings, + unknown +> = z.pipe( + z.object({ + business_memory_daily_cap: z.int(), + business_memory_enabled: z.boolean(), + is_default: z.boolean(), + organization_id: z.string(), + work_units_daily_cap: z.int(), + work_units_enabled: z.boolean(), + }), + z.transform((v) => { + return remap$(v, { + "business_memory_daily_cap": "businessMemoryDailyCap", + "business_memory_enabled": "businessMemoryEnabled", + "is_default": "isDefault", + "organization_id": "organizationId", + "work_units_daily_cap": "workUnitsDailyCap", + "work_units_enabled": "workUnitsEnabled", + }); + }), +); + +export function adminChatAnalysisSettingsFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminChatAnalysisSettings$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminChatAnalysisSettings' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminchatanalysistriggerresult.ts b/client/admin/src/sdk/src/models/components/adminchatanalysistriggerresult.ts new file mode 100644 index 00000000000..2d85fd9cfaa --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminchatanalysistriggerresult.ts @@ -0,0 +1,38 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminChatAnalysisTriggerResult = { + projectsSignaled: number; +}; + +/** @internal */ +export const AdminChatAnalysisTriggerResult$inboundSchema: z.ZodMiniType< + AdminChatAnalysisTriggerResult, + unknown +> = z.pipe( + z.object({ + projects_signaled: z.int(), + }), + z.transform((v) => { + return remap$(v, { + "projects_signaled": "projectsSignaled", + }); + }), +); + +export function adminChatAnalysisTriggerResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminChatAnalysisTriggerResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminChatAnalysisTriggerResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/admininferencekey.ts b/client/admin/src/sdk/src/models/components/admininferencekey.ts new file mode 100644 index 00000000000..751a39beb58 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/admininferencekey.ts @@ -0,0 +1,64 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Current usage and configured state for one materialized platform-managed OpenRouter key, without key material or provider identifiers. + */ +export type AdminInferenceKey = { + /** + * Credits spent this month in USD. + */ + creditsUsed: number; + /** + * Active internal disable causes. Omitted for legacy unclassified rows. + */ + disableCauses?: Array | undefined; + /** + * Whether disable_causes is classified, including an explicitly empty cause set. + */ + disableCausesClassified: boolean; + disabled: boolean; + keyType: string; + monthlyCredits: number; +}; + +/** @internal */ +export const AdminInferenceKey$inboundSchema: z.ZodMiniType< + AdminInferenceKey, + unknown +> = z.pipe( + z.object({ + credits_used: z.number(), + disable_causes: z.optional(z.array(z.string())), + disable_causes_classified: z.boolean(), + disabled: z.boolean(), + key_type: z.string(), + monthly_credits: z.int(), + }), + z.transform((v) => { + return remap$(v, { + "credits_used": "creditsUsed", + "disable_causes": "disableCauses", + "disable_causes_classified": "disableCausesClassified", + "key_type": "keyType", + "monthly_credits": "monthlyCredits", + }); + }), +); + +export function adminInferenceKeyFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminInferenceKey$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminInferenceKey' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/admininferencekeylimit.ts b/client/admin/src/sdk/src/models/components/admininferencekeylimit.ts new file mode 100644 index 00000000000..852f15b551b --- /dev/null +++ b/client/admin/src/sdk/src/models/components/admininferencekeylimit.ts @@ -0,0 +1,44 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * The configured monthly limit for one materialized platform-managed OpenRouter key. + */ +export type AdminInferenceKeyLimit = { + keyType: string; + monthlyCredits: number; +}; + +/** @internal */ +export const AdminInferenceKeyLimit$inboundSchema: z.ZodMiniType< + AdminInferenceKeyLimit, + unknown +> = z.pipe( + z.object({ + key_type: z.string(), + monthly_credits: z.int(), + }), + z.transform((v) => { + return remap$(v, { + "key_type": "keyType", + "monthly_credits": "monthlyCredits", + }); + }), +); + +export function adminInferenceKeyLimitFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminInferenceKeyLimit$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminInferenceKeyLimit' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/admininferencespendmonth.ts b/client/admin/src/sdk/src/models/components/admininferencespendmonth.ts new file mode 100644 index 00000000000..96144c801a1 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/admininferencespendmonth.ts @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { RFCDate } from "../../types/rfcdate.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminInferenceSpendMonth = { + /** + * Exclusive end of the UTC calendar month. + */ + periodEnd: RFCDate; + periodStart: RFCDate; + spendUsd: string; +}; + +/** @internal */ +export const AdminInferenceSpendMonth$inboundSchema: z.ZodMiniType< + AdminInferenceSpendMonth, + unknown +> = z.pipe( + z.object({ + period_end: z.pipe(z.string(), z.transform(v => new RFCDate(v))), + period_start: z.pipe(z.string(), z.transform(v => new RFCDate(v))), + spend_usd: z.string(), + }), + z.transform((v) => { + return remap$(v, { + "period_end": "periodEnd", + "period_start": "periodStart", + "spend_usd": "spendUsd", + }); + }), +); + +export function adminInferenceSpendMonthFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminInferenceSpendMonth$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminInferenceSpendMonth' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminlistorganizationactivityresult.ts b/client/admin/src/sdk/src/models/components/adminlistorganizationactivityresult.ts new file mode 100644 index 00000000000..563142ad7df --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminlistorganizationactivityresult.ts @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import { AuditLog, AuditLog$inboundSchema } from "./auditlog.js"; + +export type AdminListOrganizationActivityResult = { + /** + * List of organization activity. + */ + logs: Array; + /** + * Cursor for the next page of results. + */ + nextCursor?: string | undefined; +}; + +/** @internal */ +export const AdminListOrganizationActivityResult$inboundSchema: z.ZodMiniType< + AdminListOrganizationActivityResult, + unknown +> = z.pipe( + z.object({ + logs: z.array(AuditLog$inboundSchema), + next_cursor: z.optional(z.string()), + }), + z.transform((v) => { + return remap$(v, { + "next_cursor": "nextCursor", + }); + }), +); + +export function adminListOrganizationActivityResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => + AdminListOrganizationActivityResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationActivityResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminlistorganizationmembersresult.ts b/client/admin/src/sdk/src/models/components/adminlistorganizationmembersresult.ts new file mode 100644 index 00000000000..9dfbaed0bb0 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminlistorganizationmembersresult.ts @@ -0,0 +1,38 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import { + AdminOrganizationMember, + AdminOrganizationMember$inboundSchema, +} from "./adminorganizationmember.js"; + +export type AdminListOrganizationMembersResult = { + /** + * The members of the organization. + */ + members: Array; +}; + +/** @internal */ +export const AdminListOrganizationMembersResult$inboundSchema: z.ZodMiniType< + AdminListOrganizationMembersResult, + unknown +> = z.object({ + members: z.array(AdminOrganizationMember$inboundSchema), +}); + +export function adminListOrganizationMembersResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => + AdminListOrganizationMembersResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationMembersResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminlistorganizationprojectsresult.ts b/client/admin/src/sdk/src/models/components/adminlistorganizationprojectsresult.ts new file mode 100644 index 00000000000..18eca1fc9f0 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminlistorganizationprojectsresult.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import { AdminProject, AdminProject$inboundSchema } from "./adminproject.js"; + +export type AdminListOrganizationProjectsResult = { + /** + * The projects belonging to the organization. + */ + projects: Array; +}; + +/** @internal */ +export const AdminListOrganizationProjectsResult$inboundSchema: z.ZodMiniType< + AdminListOrganizationProjectsResult, + unknown +> = z.object({ + projects: z.array(AdminProject$inboundSchema), +}); + +export function adminListOrganizationProjectsResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => + AdminListOrganizationProjectsResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationProjectsResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminlistorganizationsresult.ts b/client/admin/src/sdk/src/models/components/adminlistorganizationsresult.ts new file mode 100644 index 00000000000..07a35f237b1 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminlistorganizationsresult.ts @@ -0,0 +1,55 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import { + AdminOrganization, + AdminOrganization$inboundSchema, +} from "./adminorganization.js"; + +export type AdminListOrganizationsResult = { + /** + * Cursor for the next page; empty when exhausted. Omitted in offset mode. + */ + nextCursor?: string | undefined; + /** + * The page of organizations. + */ + organizations: Array; + /** + * Number of organizations matching the filters, before paging. + */ + total: number; +}; + +/** @internal */ +export const AdminListOrganizationsResult$inboundSchema: z.ZodMiniType< + AdminListOrganizationsResult, + unknown +> = z.pipe( + z.object({ + next_cursor: z.optional(z.string()), + organizations: z.array(AdminOrganization$inboundSchema), + total: z.int(), + }), + z.transform((v) => { + return remap$(v, { + "next_cursor": "nextCursor", + }); + }), +); + +export function adminListOrganizationsResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminListOrganizationsResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationsResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminorganization.ts b/client/admin/src/sdk/src/models/components/adminorganization.ts new file mode 100644 index 00000000000..9c1e35a3be1 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminorganization.ts @@ -0,0 +1,159 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { ClosedEnum } from "../../types/enums.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Lifecycle state of the organization's enterprise trial. + */ +export const TrialState = { + None: "none", + Running: "running", + EndingSoon: "ending_soon", + Expired: "expired", + Demoted: "demoted", + Converted: "converted", +} as const; +/** + * Lifecycle state of the organization's enterprise trial. + */ +export type TrialState = ClosedEnum; + +/** + * Organization details surfaced to admin operators. + */ +export type AdminOrganization = { + /** + * Gram account type (e.g. free, pro, payg, enterprise). + */ + accountType: string; + /** + * The creation date of the organization. + */ + createdAt: Date; + /** + * The time at which the organization was disabled, if any. + */ + disabledAt?: Date | undefined; + /** + * The ID of the organization + */ + id: string; + /** + * Number of active members in the organization. + */ + memberCount: number; + /** + * The name of the organization + */ + name: string; + /** + * The slug of the organization + */ + slug: string; + /** + * The time at which the trial converted to a paid plan, if any. + */ + trialConvertedAt?: Date | undefined; + /** + * The time at which the organization was demoted after its trial, if any. + */ + trialDemotedAt?: Date | undefined; + /** + * The time at which the enterprise trial ends. Absent when the organization never trialled. + */ + trialEndsAt?: Date | undefined; + /** + * Lifecycle state of the organization's enterprise trial. + */ + trialState?: TrialState | undefined; + /** + * The trial tier. Absent when the organization never trialled. + */ + trialTier?: string | undefined; + /** + * The last update date of the organization. + */ + updatedAt: Date; + /** + * Whether the organization is whitelisted for full access. + */ + whitelisted: boolean; + /** + * WorkOS organization ID, if linked. + */ + workosId?: string | undefined; +}; + +/** @internal */ +export const TrialState$inboundSchema: z.ZodMiniEnum = z + .enum(TrialState); + +/** @internal */ +export const AdminOrganization$inboundSchema: z.ZodMiniType< + AdminOrganization, + unknown +> = z.pipe( + z.object({ + account_type: z.string(), + created_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + disabled_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + id: z.string(), + member_count: z.int(), + name: z.string(), + slug: z.string(), + trial_converted_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + trial_demoted_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + trial_ends_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + trial_state: z.optional(TrialState$inboundSchema), + trial_tier: z.optional(z.string()), + updated_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + whitelisted: z.boolean(), + workos_id: z.optional(z.string()), + }), + z.transform((v) => { + return remap$(v, { + "account_type": "accountType", + "created_at": "createdAt", + "disabled_at": "disabledAt", + "member_count": "memberCount", + "trial_converted_at": "trialConvertedAt", + "trial_demoted_at": "trialDemotedAt", + "trial_ends_at": "trialEndsAt", + "trial_state": "trialState", + "trial_tier": "trialTier", + "updated_at": "updatedAt", + "workos_id": "workosId", + }); + }), +); + +export function adminOrganizationFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminOrganization$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminOrganization' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminorganizationmember.ts b/client/admin/src/sdk/src/models/components/adminorganizationmember.ts new file mode 100644 index 00000000000..508cc774df5 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminorganizationmember.ts @@ -0,0 +1,74 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Organization member surfaced to admin operators. + */ +export type AdminOrganizationMember = { + createdAt: Date; + /** + * User display name. + */ + displayName: string; + /** + * User email address. + */ + email: string; + /** + * User ID. + */ + id: string; + /** + * The time the user last logged in, if any. + */ + lastLogin?: Date | undefined; + updatedAt: Date; +}; + +/** @internal */ +export const AdminOrganizationMember$inboundSchema: z.ZodMiniType< + AdminOrganizationMember, + unknown +> = z.pipe( + z.object({ + created_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + display_name: z.string(), + email: z.string(), + id: z.string(), + last_login: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + updated_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + }), + z.transform((v) => { + return remap$(v, { + "created_at": "createdAt", + "display_name": "displayName", + "last_login": "lastLogin", + "updated_at": "updatedAt", + }); + }), +); + +export function adminOrganizationMemberFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminOrganizationMember$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminOrganizationMember' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminorganizationstats.ts b/client/admin/src/sdk/src/models/components/adminorganizationstats.ts new file mode 100644 index 00000000000..c5df9051e77 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminorganizationstats.ts @@ -0,0 +1,77 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Platform-wide organization counts surfaced above the admin organizations list. + */ +export type AdminOrganizationStats = { + /** + * Organizations created in the last 7 days, whatever their current status. + */ + createdLast7Days: number; + /** + * Organizations on a paid account type (payg or enterprise), disabled ones included. + */ + customers: number; + /** + * Customers created in the last 7 days, whatever their current status. + */ + customersCreatedLast7Days: number; + /** + * Organizations with disabled_at set. + */ + disabled: number; + /** + * Organizations disabled in the last 7 days. + */ + disabledLast7Days: number; + /** + * Every organization on the platform, disabled ones included. + */ + total: number; + /** + * Organizations whose trial_state is ending_soon. + */ + trialsEndingSoon: number; +}; + +/** @internal */ +export const AdminOrganizationStats$inboundSchema: z.ZodMiniType< + AdminOrganizationStats, + unknown +> = z.pipe( + z.object({ + created_last_7_days: z.int(), + customers: z.int(), + customers_created_last_7_days: z.int(), + disabled: z.int(), + disabled_last_7_days: z.int(), + total: z.int(), + trials_ending_soon: z.int(), + }), + z.transform((v) => { + return remap$(v, { + "created_last_7_days": "createdLast7Days", + "customers_created_last_7_days": "customersCreatedLast7Days", + "disabled_last_7_days": "disabledLast7Days", + "trials_ending_soon": "trialsEndingSoon", + }); + }), +); + +export function adminOrganizationStatsFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminOrganizationStats$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminOrganizationStats' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminpaygbillingsummary.ts b/client/admin/src/sdk/src/models/components/adminpaygbillingsummary.ts new file mode 100644 index 00000000000..c2542eb1c35 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminpaygbillingsummary.ts @@ -0,0 +1,68 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { RFCDate } from "../../types/rfcdate.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminPaygBillingSummary = { + estimatedTotalUsd: string; + otherInferenceSpendUsd: string; + periodEnd: Date; + periodStart: Date; + recordedThrough?: RFCDate | undefined; + tumCostUsd: string; + tumTokens: number; + tumUnitPriceUsd: string; +}; + +/** @internal */ +export const AdminPaygBillingSummary$inboundSchema: z.ZodMiniType< + AdminPaygBillingSummary, + unknown +> = z.pipe( + z.object({ + estimated_total_usd: z.string(), + other_inference_spend_usd: z.string(), + period_end: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + period_start: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + recorded_through: z.optional( + z.pipe(z.string(), z.transform(v => new RFCDate(v))), + ), + tum_cost_usd: z.string(), + tum_tokens: z.int(), + tum_unit_price_usd: z.string(), + }), + z.transform((v) => { + return remap$(v, { + "estimated_total_usd": "estimatedTotalUsd", + "other_inference_spend_usd": "otherInferenceSpendUsd", + "period_end": "periodEnd", + "period_start": "periodStart", + "recorded_through": "recordedThrough", + "tum_cost_usd": "tumCostUsd", + "tum_tokens": "tumTokens", + "tum_unit_price_usd": "tumUnitPriceUsd", + }); + }), +); + +export function adminPaygBillingSummaryFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminPaygBillingSummary$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminPaygBillingSummary' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminproject.ts b/client/admin/src/sdk/src/models/components/adminproject.ts new file mode 100644 index 00000000000..299cfba5b89 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminproject.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Project summary surfaced to admin operators. + */ +export type AdminProject = { + /** + * The creation date of the project. + */ + createdAt: Date; + /** + * The ID of the project + */ + id: string; + /** + * Number of MCP servers in the project, counting both toolset-backed servers and mcp_servers rows. + */ + mcpServerCount: number; + /** + * The name of the project + */ + name: string; + /** + * The slug of the project + */ + slug: string; + /** + * The last update date of the project. + */ + updatedAt: Date; +}; + +/** @internal */ +export const AdminProject$inboundSchema: z.ZodMiniType = + z.pipe( + z.object({ + created_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + id: z.string(), + mcp_server_count: z.int(), + name: z.string(), + slug: z.string(), + updated_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + }), + z.transform((v) => { + return remap$(v, { + "created_at": "createdAt", + "mcp_server_count": "mcpServerCount", + "updated_at": "updatedAt", + }); + }), + ); + +export function adminProjectFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminProject$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminProject' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminprojectdetail.ts b/client/admin/src/sdk/src/models/components/adminprojectdetail.ts new file mode 100644 index 00000000000..c55b73926be --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminprojectdetail.ts @@ -0,0 +1,119 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Full project detail surfaced to admin operators, including aggregated counts of child resources. + */ +export type AdminProjectDetail = { + /** + * Number of active API keys in the project. + */ + apiKeyCount: number; + /** + * Number of active assistants in the project. + */ + assistantCount: number; + createdAt: Date; + /** + * Total number of deployments in the project. + */ + deploymentCount: number; + /** + * Number of active environments in the project. + */ + environmentCount: number; + /** + * Functions runner version pin, if set. + */ + functionsRunnerVersion?: string | undefined; + /** + * Number of active HTTP tool definitions in the project. + */ + httpToolCount: number; + /** + * Project ID. + */ + id: string; + /** + * Project logo asset ID, if set. + */ + logoAssetId?: string | undefined; + /** + * Project name. + */ + name: string; + /** + * Owning organization ID. + */ + organizationId: string; + /** + * Project slug. + */ + slug: string; + /** + * Number of active toolsets in the project. + */ + toolsetCount: number; + updatedAt: Date; +}; + +/** @internal */ +export const AdminProjectDetail$inboundSchema: z.ZodMiniType< + AdminProjectDetail, + unknown +> = z.pipe( + z.object({ + api_key_count: z.int(), + assistant_count: z.int(), + created_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + deployment_count: z.int(), + environment_count: z.int(), + functions_runner_version: z.optional(z.string()), + http_tool_count: z.int(), + id: z.string(), + logo_asset_id: z.optional(z.string()), + name: z.string(), + organization_id: z.string(), + slug: z.string(), + toolset_count: z.int(), + updated_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + }), + z.transform((v) => { + return remap$(v, { + "api_key_count": "apiKeyCount", + "assistant_count": "assistantCount", + "created_at": "createdAt", + "deployment_count": "deploymentCount", + "environment_count": "environmentCount", + "functions_runner_version": "functionsRunnerVersion", + "http_tool_count": "httpToolCount", + "logo_asset_id": "logoAssetId", + "organization_id": "organizationId", + "toolset_count": "toolsetCount", + "updated_at": "updatedAt", + }); + }), +); + +export function adminProjectDetailFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminProjectDetail$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminProjectDetail' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminsession.ts b/client/admin/src/sdk/src/models/components/adminsession.ts new file mode 100644 index 00000000000..bf0dd8edbe9 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminsession.ts @@ -0,0 +1,30 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminSession = { + email: string; + name?: string | undefined; +}; + +/** @internal */ +export const AdminSession$inboundSchema: z.ZodMiniType = + z.object({ + email: z.string(), + name: z.optional(z.string()), + }); + +export function adminSessionFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminSession$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminSession' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/adminstripesubscription.ts b/client/admin/src/sdk/src/models/components/adminstripesubscription.ts new file mode 100644 index 00000000000..a526c6ba5c4 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/adminstripesubscription.ts @@ -0,0 +1,93 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { ClosedEnum } from "../../types/enums.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export const Status = { + Incomplete: "incomplete", + IncompleteExpired: "incomplete_expired", + Trialing: "trialing", + Active: "active", + PastDue: "past_due", + Canceled: "canceled", + Unpaid: "unpaid", + Paused: "paused", +} as const; +export type Status = ClosedEnum; + +export type AdminStripeSubscription = { + cancelAt?: Date | undefined; + cancelAtPeriodEnd: boolean; + canceledAt?: Date | undefined; + currentPeriodEnd: Date; + currentPeriodStart: Date; + paymentFailed: boolean; + status: Status; + trialEnd?: Date | undefined; + trialStart?: Date | undefined; +}; + +/** @internal */ +export const Status$inboundSchema: z.ZodMiniEnum = z.enum( + Status, +); + +/** @internal */ +export const AdminStripeSubscription$inboundSchema: z.ZodMiniType< + AdminStripeSubscription, + unknown +> = z.pipe( + z.object({ + cancel_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + cancel_at_period_end: z.boolean(), + canceled_at: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + current_period_end: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + current_period_start: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + payment_failed: z.boolean(), + status: Status$inboundSchema, + trial_end: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + trial_start: z.optional( + z.pipe(z.iso.datetime({ offset: true }), z.transform(v => new Date(v))), + ), + }), + z.transform((v) => { + return remap$(v, { + "cancel_at": "cancelAt", + "cancel_at_period_end": "cancelAtPeriodEnd", + "canceled_at": "canceledAt", + "current_period_end": "currentPeriodEnd", + "current_period_start": "currentPeriodStart", + "payment_failed": "paymentFailed", + "trial_end": "trialEnd", + "trial_start": "trialStart", + }); + }), +); + +export function adminStripeSubscriptionFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminStripeSubscription$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminStripeSubscription' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/auditlog.ts b/client/admin/src/sdk/src/models/components/auditlog.ts new file mode 100644 index 00000000000..77ad9b768e6 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/auditlog.ts @@ -0,0 +1,95 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AuditLog = { + /** + * The registered OAuth client the call authenticated as, when it had one. Absent for calls that carried no OAuth client. + */ + actingClientId?: string | undefined; + /** + * How the change was made: 'dashboard', 'api_key', 'platform_mcp', 'project_assistant', or 'unknown' when no surface was identifiable. Always present. + */ + actingSurface: string; + action: string; + actorDisplayName?: string | undefined; + actorId: string; + actorSlug?: string | undefined; + actorType: string; + afterSnapshot?: any | undefined; + beforeSnapshot?: any | undefined; + /** + * The creation date of the audit log. + */ + createdAt: Date; + id: string; + metadata?: { [k: string]: any } | undefined; + projectId?: string | undefined; + projectSlug?: string | undefined; + subjectDisplayName?: string | undefined; + subjectId: string; + subjectSlug?: string | undefined; + subjectType: string; +}; + +/** @internal */ +export const AuditLog$inboundSchema: z.ZodMiniType = z.pipe( + z.object({ + acting_client_id: z.optional(z.string()), + acting_surface: z.string(), + action: z.string(), + actor_display_name: z.optional(z.string()), + actor_id: z.string(), + actor_slug: z.optional(z.string()), + actor_type: z.string(), + after_snapshot: z.optional(z.any()), + before_snapshot: z.optional(z.any()), + created_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + id: z.string(), + metadata: z.optional(z.record(z.string(), z.any())), + project_id: z.optional(z.string()), + project_slug: z.optional(z.string()), + subject_display_name: z.optional(z.string()), + subject_id: z.string(), + subject_slug: z.optional(z.string()), + subject_type: z.string(), + }), + z.transform((v) => { + return remap$(v, { + "acting_client_id": "actingClientId", + "acting_surface": "actingSurface", + "actor_display_name": "actorDisplayName", + "actor_id": "actorId", + "actor_slug": "actorSlug", + "actor_type": "actorType", + "after_snapshot": "afterSnapshot", + "before_snapshot": "beforeSnapshot", + "created_at": "createdAt", + "project_id": "projectId", + "project_slug": "projectSlug", + "subject_display_name": "subjectDisplayName", + "subject_id": "subjectId", + "subject_slug": "subjectSlug", + "subject_type": "subjectType", + }); + }), +); + +export function auditLogFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AuditLog$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AuditLog' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/bulkupdateaccounttyperequestbody.ts b/client/admin/src/sdk/src/models/components/bulkupdateaccounttyperequestbody.ts new file mode 100644 index 00000000000..77960f3f0fb --- /dev/null +++ b/client/admin/src/sdk/src/models/components/bulkupdateaccounttyperequestbody.ts @@ -0,0 +1,72 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { ClosedEnum } from "../../types/enums.js"; + +/** + * New gram_account_type for every listed organization. + */ +export const BulkUpdateAccountTypeRequestBodyAccountType = { + Free: "free", + Pro: "pro", + Payg: "payg", + Enterprise: "enterprise", +} as const; +/** + * New gram_account_type for every listed organization. + */ +export type BulkUpdateAccountTypeRequestBodyAccountType = ClosedEnum< + typeof BulkUpdateAccountTypeRequestBodyAccountType +>; + +export type BulkUpdateAccountTypeRequestBody = { + /** + * New gram_account_type for every listed organization. + */ + accountType: BulkUpdateAccountTypeRequestBodyAccountType; + /** + * Organization IDs to update. + */ + ids: Array; +}; + +/** @internal */ +export const BulkUpdateAccountTypeRequestBodyAccountType$outboundSchema: + z.ZodMiniEnum = z.enum( + BulkUpdateAccountTypeRequestBodyAccountType, + ); + +/** @internal */ +export type BulkUpdateAccountTypeRequestBody$Outbound = { + account_type: string; + ids: Array; +}; + +/** @internal */ +export const BulkUpdateAccountTypeRequestBody$outboundSchema: z.ZodMiniType< + BulkUpdateAccountTypeRequestBody$Outbound, + BulkUpdateAccountTypeRequestBody +> = z.pipe( + z.object({ + accountType: BulkUpdateAccountTypeRequestBodyAccountType$outboundSchema, + ids: z.array(z.string()), + }), + z.transform((v) => { + return remap$(v, { + accountType: "account_type", + }); + }), +); + +export function bulkUpdateAccountTypeRequestBodyToJSON( + bulkUpdateAccountTypeRequestBody: BulkUpdateAccountTypeRequestBody, +): string { + return JSON.stringify( + BulkUpdateAccountTypeRequestBody$outboundSchema.parse( + bulkUpdateAccountTypeRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/cancelstripesubscriptionrequestbody.ts b/client/admin/src/sdk/src/models/components/cancelstripesubscriptionrequestbody.ts new file mode 100644 index 00000000000..3253706e66a --- /dev/null +++ b/client/admin/src/sdk/src/models/components/cancelstripesubscriptionrequestbody.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type CancelStripeSubscriptionRequestBody = { + organizationId: string; +}; + +/** @internal */ +export type CancelStripeSubscriptionRequestBody$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const CancelStripeSubscriptionRequestBody$outboundSchema: z.ZodMiniType< + CancelStripeSubscriptionRequestBody$Outbound, + CancelStripeSubscriptionRequestBody +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function cancelStripeSubscriptionRequestBodyToJSON( + cancelStripeSubscriptionRequestBody: CancelStripeSubscriptionRequestBody, +): string { + return JSON.stringify( + CancelStripeSubscriptionRequestBody$outboundSchema.parse( + cancelStripeSubscriptionRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/createorganizationrequestbody.ts b/client/admin/src/sdk/src/models/components/createorganizationrequestbody.ts new file mode 100644 index 00000000000..e1f1beecc65 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/createorganizationrequestbody.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type CreateOrganizationRequestBody = { + /** + * Display name for the new organization. + */ + name: string; +}; + +/** @internal */ +export type CreateOrganizationRequestBody$Outbound = { + name: string; +}; + +/** @internal */ +export const CreateOrganizationRequestBody$outboundSchema: z.ZodMiniType< + CreateOrganizationRequestBody$Outbound, + CreateOrganizationRequestBody +> = z.object({ + name: z.string(), +}); + +export function createOrganizationRequestBodyToJSON( + createOrganizationRequestBody: CreateOrganizationRequestBody, +): string { + return JSON.stringify( + CreateOrganizationRequestBody$outboundSchema.parse( + createOrganizationRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/disableorganizationrequestbody.ts b/client/admin/src/sdk/src/models/components/disableorganizationrequestbody.ts new file mode 100644 index 00000000000..3dca7461642 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/disableorganizationrequestbody.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type DisableOrganizationRequestBody = { + /** + * Organization ID. + */ + id: string; +}; + +/** @internal */ +export type DisableOrganizationRequestBody$Outbound = { + id: string; +}; + +/** @internal */ +export const DisableOrganizationRequestBody$outboundSchema: z.ZodMiniType< + DisableOrganizationRequestBody$Outbound, + DisableOrganizationRequestBody +> = z.object({ + id: z.string(), +}); + +export function disableOrganizationRequestBodyToJSON( + disableOrganizationRequestBody: DisableOrganizationRequestBody, +): string { + return JSON.stringify( + DisableOrganizationRequestBody$outboundSchema.parse( + disableOrganizationRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/enableorganizationrequestbody.ts b/client/admin/src/sdk/src/models/components/enableorganizationrequestbody.ts new file mode 100644 index 00000000000..faa6d0a97f0 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/enableorganizationrequestbody.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type EnableOrganizationRequestBody = { + /** + * Organization ID. + */ + id: string; +}; + +/** @internal */ +export type EnableOrganizationRequestBody$Outbound = { + id: string; +}; + +/** @internal */ +export const EnableOrganizationRequestBody$outboundSchema: z.ZodMiniType< + EnableOrganizationRequestBody$Outbound, + EnableOrganizationRequestBody +> = z.object({ + id: z.string(), +}); + +export function enableOrganizationRequestBodyToJSON( + enableOrganizationRequestBody: EnableOrganizationRequestBody, +): string { + return JSON.stringify( + EnableOrganizationRequestBody$outboundSchema.parse( + enableOrganizationRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/extendtrialrequestbody.ts b/client/admin/src/sdk/src/models/components/extendtrialrequestbody.ts new file mode 100644 index 00000000000..b8f65c1817c --- /dev/null +++ b/client/admin/src/sdk/src/models/components/extendtrialrequestbody.ts @@ -0,0 +1,39 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type ExtendTrialRequestBody = { + /** + * Number of days to add to the trial's current end date. + */ + days: number; + /** + * Organization ID. + */ + id: string; +}; + +/** @internal */ +export type ExtendTrialRequestBody$Outbound = { + days: number; + id: string; +}; + +/** @internal */ +export const ExtendTrialRequestBody$outboundSchema: z.ZodMiniType< + ExtendTrialRequestBody$Outbound, + ExtendTrialRequestBody +> = z.object({ + days: z.int(), + id: z.string(), +}); + +export function extendTrialRequestBodyToJSON( + extendTrialRequestBody: ExtendTrialRequestBody, +): string { + return JSON.stringify( + ExtendTrialRequestBody$outboundSchema.parse(extendTrialRequestBody), + ); +} diff --git a/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedrequestbody.ts b/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedrequestbody.ts new file mode 100644 index 00000000000..5b908ffc5ae --- /dev/null +++ b/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedrequestbody.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type MarkEnterpriseTrialConvertedRequestBody = { + /** + * Organization ID. + */ + id: string; +}; + +/** @internal */ +export type MarkEnterpriseTrialConvertedRequestBody$Outbound = { + id: string; +}; + +/** @internal */ +export const MarkEnterpriseTrialConvertedRequestBody$outboundSchema: + z.ZodMiniType< + MarkEnterpriseTrialConvertedRequestBody$Outbound, + MarkEnterpriseTrialConvertedRequestBody + > = z.object({ + id: z.string(), + }); + +export function markEnterpriseTrialConvertedRequestBodyToJSON( + markEnterpriseTrialConvertedRequestBody: + MarkEnterpriseTrialConvertedRequestBody, +): string { + return JSON.stringify( + MarkEnterpriseTrialConvertedRequestBody$outboundSchema.parse( + markEnterpriseTrialConvertedRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedresult.ts b/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedresult.ts new file mode 100644 index 00000000000..0b74a90d10a --- /dev/null +++ b/client/admin/src/sdk/src/models/components/markenterprisetrialconvertedresult.ts @@ -0,0 +1,54 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Privacy-minimal result of recording an enterprise trial conversion. + */ +export type MarkEnterpriseTrialConvertedResult = { + /** + * The time at which the enterprise trial was recorded as converted. + */ + convertedAt: Date; + /** + * The converted organization ID. + */ + organizationId: string; +}; + +/** @internal */ +export const MarkEnterpriseTrialConvertedResult$inboundSchema: z.ZodMiniType< + MarkEnterpriseTrialConvertedResult, + unknown +> = z.pipe( + z.object({ + converted_at: z.pipe( + z.iso.datetime({ offset: true }), + z.transform(v => new Date(v)), + ), + organization_id: z.string(), + }), + z.transform((v) => { + return remap$(v, { + "converted_at": "convertedAt", + "organization_id": "organizationId", + }); + }), +); + +export function markEnterpriseTrialConvertedResultFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => + MarkEnterpriseTrialConvertedResult$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'MarkEnterpriseTrialConvertedResult' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/productfeatures.ts b/client/admin/src/sdk/src/models/components/productfeatures.ts new file mode 100644 index 00000000000..7dc4a9ad194 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/productfeatures.ts @@ -0,0 +1,152 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type ProductFeatures = { + /** + * Whether the organization can provision push integrations for AI platforms + */ + aiPlatformPushIntegrationsEnabled: boolean; + /** + * Whether authz challenge logging to ClickHouse is enabled + */ + authzChallengeLoggingEnabled: boolean; + /** + * Whether MCP consent screens offer the tool filtering picker for the organization + */ + consentToolFilteringEnabled: boolean; + /** + * Whether the organization can supply its own model provider API keys (BYOK) + */ + customModelKeysEnabled: boolean; + /** + * Whether the organization can manage the external credentials and cloud KMS keys backing customer-managed encryption + */ + customerManagedEncryptionKeysEnabled: boolean; + /** + * Whether the organization uses the device agent (any device has polled agent.getPlugins). Derived from device-agent syncs, not an admin-settable feature. + */ + deviceAgent: boolean; + /** + * Whether generated hook plugins may mint per-user keys via the interactive browser login + */ + hooksBrowserLoginEnabled: boolean; + /** + * Whether hooks fail open when the Speakeasy control plane is unreachable or erroring — blocking policies are not enforced for the duration of the outage + */ + hooksFailOpenEnabled: boolean; + /** + * Whether logging is enabled + */ + logsEnabled: boolean; + /** + * Whether the organization can use the Gram Platform MCP capability + */ + platformMcpEnabled: boolean; + /** + * Whether consent screens expose automatic remote-session refresh for the organization + */ + remoteSessionAutoRefreshEnabled: boolean; + /** + * Whether automatic remote-session refresh is enforced as the organization default: forced on for every user, shown locked on consent screens, and applied by the keepalive regardless of per-session preference + */ + remoteSessionAutoRefreshEnforcedEnabled: boolean; + /** + * Whether SCIM/directory sync setup is enabled for the organization + */ + scimEnabled: boolean; + /** + * Whether Claude Code session capture is enabled + */ + sessionCaptureEnabled: boolean; + /** + * Whether agent session portability is enabled for the organization: session sharing links, move reporting with lineage, and picker title enrichment via the device agent + */ + sessionPortabilityEnabled: boolean; + /** + * Whether skill capture stores activation metadata without requesting manifest content + */ + skillCaptureMetadataOnly: boolean; + /** + * Whether the Skills page is enabled for the organization + */ + skillsEnabled: boolean; + /** + * Whether SSO setup is enabled for the organization + */ + ssoEnabled: boolean; + /** + * Whether tool I/O logging is enabled + */ + toolIoLogsEnabled: boolean; +}; + +/** @internal */ +export const ProductFeatures$inboundSchema: z.ZodMiniType< + ProductFeatures, + unknown +> = z.pipe( + z.object({ + ai_platform_push_integrations_enabled: z.boolean(), + authz_challenge_logging_enabled: z.boolean(), + consent_tool_filtering_enabled: z.boolean(), + custom_model_keys_enabled: z.boolean(), + customer_managed_encryption_keys_enabled: z.boolean(), + device_agent: z.boolean(), + hooks_browser_login_enabled: z.boolean(), + hooks_fail_open_enabled: z.boolean(), + logs_enabled: z.boolean(), + platform_mcp_enabled: z.boolean(), + remote_session_auto_refresh_enabled: z.boolean(), + remote_session_auto_refresh_enforced_enabled: z.boolean(), + scim_enabled: z.boolean(), + session_capture_enabled: z.boolean(), + session_portability_enabled: z.boolean(), + skill_capture_metadata_only: z.boolean(), + skills_enabled: z.boolean(), + sso_enabled: z.boolean(), + tool_io_logs_enabled: z.boolean(), + }), + z.transform((v) => { + return remap$(v, { + "ai_platform_push_integrations_enabled": + "aiPlatformPushIntegrationsEnabled", + "authz_challenge_logging_enabled": "authzChallengeLoggingEnabled", + "consent_tool_filtering_enabled": "consentToolFilteringEnabled", + "custom_model_keys_enabled": "customModelKeysEnabled", + "customer_managed_encryption_keys_enabled": + "customerManagedEncryptionKeysEnabled", + "device_agent": "deviceAgent", + "hooks_browser_login_enabled": "hooksBrowserLoginEnabled", + "hooks_fail_open_enabled": "hooksFailOpenEnabled", + "logs_enabled": "logsEnabled", + "platform_mcp_enabled": "platformMcpEnabled", + "remote_session_auto_refresh_enabled": "remoteSessionAutoRefreshEnabled", + "remote_session_auto_refresh_enforced_enabled": + "remoteSessionAutoRefreshEnforcedEnabled", + "scim_enabled": "scimEnabled", + "session_capture_enabled": "sessionCaptureEnabled", + "session_portability_enabled": "sessionPortabilityEnabled", + "skill_capture_metadata_only": "skillCaptureMetadataOnly", + "skills_enabled": "skillsEnabled", + "sso_enabled": "ssoEnabled", + "tool_io_logs_enabled": "toolIoLogsEnabled", + }); + }), +); + +export function productFeaturesFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => ProductFeatures$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'ProductFeatures' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/components/rearmtrialrequestbody.ts b/client/admin/src/sdk/src/models/components/rearmtrialrequestbody.ts new file mode 100644 index 00000000000..3c1c9f140f8 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/rearmtrialrequestbody.ts @@ -0,0 +1,39 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export type RearmTrialRequestBody = { + /** + * Number of days the re-armed trial runs for, counted from now. + */ + days: number; + /** + * Organization ID. + */ + id: string; +}; + +/** @internal */ +export type RearmTrialRequestBody$Outbound = { + days: number; + id: string; +}; + +/** @internal */ +export const RearmTrialRequestBody$outboundSchema: z.ZodMiniType< + RearmTrialRequestBody$Outbound, + RearmTrialRequestBody +> = z.object({ + days: z.int(), + id: z.string(), +}); + +export function rearmTrialRequestBodyToJSON( + rearmTrialRequestBody: RearmTrialRequestBody, +): string { + return JSON.stringify( + RearmTrialRequestBody$outboundSchema.parse(rearmTrialRequestBody), + ); +} diff --git a/client/admin/src/sdk/src/models/components/resumestripesubscriptionrequestbody.ts b/client/admin/src/sdk/src/models/components/resumestripesubscriptionrequestbody.ts new file mode 100644 index 00000000000..222af564575 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/resumestripesubscriptionrequestbody.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type ResumeStripeSubscriptionRequestBody = { + organizationId: string; +}; + +/** @internal */ +export type ResumeStripeSubscriptionRequestBody$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const ResumeStripeSubscriptionRequestBody$outboundSchema: z.ZodMiniType< + ResumeStripeSubscriptionRequestBody$Outbound, + ResumeStripeSubscriptionRequestBody +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function resumeStripeSubscriptionRequestBodyToJSON( + resumeStripeSubscriptionRequestBody: ResumeStripeSubscriptionRequestBody, +): string { + return JSON.stringify( + ResumeStripeSubscriptionRequestBody$outboundSchema.parse( + resumeStripeSubscriptionRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/setinferencekeymonthlylimitrequestbody.ts b/client/admin/src/sdk/src/models/components/setinferencekeymonthlylimitrequestbody.ts new file mode 100644 index 00000000000..70b5fb95614 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/setinferencekeymonthlylimitrequestbody.ts @@ -0,0 +1,62 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { ClosedEnum } from "../../types/enums.js"; + +export const KeyType = { + Chat: "chat", + Internal: "internal", +} as const; +export type KeyType = ClosedEnum; + +export type SetInferenceKeyMonthlyLimitRequestBody = { + keyType: KeyType; + monthlyCredits: number; + organizationId: string; +}; + +/** @internal */ +export const KeyType$outboundSchema: z.ZodMiniEnum = z.enum( + KeyType, +); + +/** @internal */ +export type SetInferenceKeyMonthlyLimitRequestBody$Outbound = { + key_type: string; + monthly_credits: number; + organization_id: string; +}; + +/** @internal */ +export const SetInferenceKeyMonthlyLimitRequestBody$outboundSchema: + z.ZodMiniType< + SetInferenceKeyMonthlyLimitRequestBody$Outbound, + SetInferenceKeyMonthlyLimitRequestBody + > = z.pipe( + z.object({ + keyType: KeyType$outboundSchema, + monthlyCredits: z.int(), + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + keyType: "key_type", + monthlyCredits: "monthly_credits", + organizationId: "organization_id", + }); + }), + ); + +export function setInferenceKeyMonthlyLimitRequestBodyToJSON( + setInferenceKeyMonthlyLimitRequestBody: + SetInferenceKeyMonthlyLimitRequestBody, +): string { + return JSON.stringify( + SetInferenceKeyMonthlyLimitRequestBody$outboundSchema.parse( + setInferenceKeyMonthlyLimitRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/setorganizationchatanalysissettingsrequestbody.ts b/client/admin/src/sdk/src/models/components/setorganizationchatanalysissettingsrequestbody.ts new file mode 100644 index 00000000000..e6f60b86f8e --- /dev/null +++ b/client/admin/src/sdk/src/models/components/setorganizationchatanalysissettingsrequestbody.ts @@ -0,0 +1,62 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { ClosedEnum } from "../../types/enums.js"; + +export const Judge = { + WorkUnits: "work_units", + BusinessMemory: "business_memory", +} as const; +export type Judge = ClosedEnum; + +export type SetOrganizationChatAnalysisSettingsRequestBody = { + dailyCap: number; + enabled: boolean; + judge: Judge; + organizationId: string; +}; + +/** @internal */ +export const Judge$outboundSchema: z.ZodMiniEnum = z.enum(Judge); + +/** @internal */ +export type SetOrganizationChatAnalysisSettingsRequestBody$Outbound = { + daily_cap: number; + enabled: boolean; + judge: string; + organization_id: string; +}; + +/** @internal */ +export const SetOrganizationChatAnalysisSettingsRequestBody$outboundSchema: + z.ZodMiniType< + SetOrganizationChatAnalysisSettingsRequestBody$Outbound, + SetOrganizationChatAnalysisSettingsRequestBody + > = z.pipe( + z.object({ + dailyCap: z.int(), + enabled: z.boolean(), + judge: Judge$outboundSchema, + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + dailyCap: "daily_cap", + organizationId: "organization_id", + }); + }), + ); + +export function setOrganizationChatAnalysisSettingsRequestBodyToJSON( + setOrganizationChatAnalysisSettingsRequestBody: + SetOrganizationChatAnalysisSettingsRequestBody, +): string { + return JSON.stringify( + SetOrganizationChatAnalysisSettingsRequestBody$outboundSchema.parse( + setOrganizationChatAnalysisSettingsRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/setorganizationfeaturerequestbody.ts b/client/admin/src/sdk/src/models/components/setorganizationfeaturerequestbody.ts new file mode 100644 index 00000000000..c991dd2359b --- /dev/null +++ b/client/admin/src/sdk/src/models/components/setorganizationfeaturerequestbody.ts @@ -0,0 +1,74 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { ClosedEnum } from "../../types/enums.js"; + +export const FeatureName = { + Logs: "logs", + ToolIoLogs: "tool_io_logs", + SessionCapture: "session_capture", + AuthzChallengeLogging: "authz_challenge_logging", + Sso: "sso", + Scim: "scim", + HooksBrowserLogin: "hooks_browser_login", + HooksFailOpen: "hooks_fail_open", + CustomModelKeys: "custom_model_keys", + Skills: "skills", + SkillCaptureMetadataOnly: "skill_capture_metadata_only", + AiPlatformPushIntegrations: "ai_platform_push_integrations", + PlatformMcp: "platform_mcp", + CustomerManagedEncryptionKeys: "customer_managed_encryption_keys", + RemoteSessionAutoRefresh: "remote_session_auto_refresh", + RemoteSessionAutoRefreshEnforced: "remote_session_auto_refresh_enforced", + ConsentToolFiltering: "consent_tool_filtering", + SessionPortability: "session_portability", +} as const; +export type FeatureName = ClosedEnum; + +export type SetOrganizationFeatureRequestBody = { + enabled: boolean; + featureName: FeatureName; + organizationId: string; +}; + +/** @internal */ +export const FeatureName$outboundSchema: z.ZodMiniEnum = z + .enum(FeatureName); + +/** @internal */ +export type SetOrganizationFeatureRequestBody$Outbound = { + enabled: boolean; + feature_name: string; + organization_id: string; +}; + +/** @internal */ +export const SetOrganizationFeatureRequestBody$outboundSchema: z.ZodMiniType< + SetOrganizationFeatureRequestBody$Outbound, + SetOrganizationFeatureRequestBody +> = z.pipe( + z.object({ + enabled: z.boolean(), + featureName: FeatureName$outboundSchema, + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + featureName: "feature_name", + organizationId: "organization_id", + }); + }), +); + +export function setOrganizationFeatureRequestBodyToJSON( + setOrganizationFeatureRequestBody: SetOrganizationFeatureRequestBody, +): string { + return JSON.stringify( + SetOrganizationFeatureRequestBody$outboundSchema.parse( + setOrganizationFeatureRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/triggerorganizationchatanalysisrequestbody.ts b/client/admin/src/sdk/src/models/components/triggerorganizationchatanalysisrequestbody.ts new file mode 100644 index 00000000000..24adf440968 --- /dev/null +++ b/client/admin/src/sdk/src/models/components/triggerorganizationchatanalysisrequestbody.ts @@ -0,0 +1,42 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type TriggerOrganizationChatAnalysisRequestBody = { + organizationId: string; +}; + +/** @internal */ +export type TriggerOrganizationChatAnalysisRequestBody$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const TriggerOrganizationChatAnalysisRequestBody$outboundSchema: + z.ZodMiniType< + TriggerOrganizationChatAnalysisRequestBody$Outbound, + TriggerOrganizationChatAnalysisRequestBody + > = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), + ); + +export function triggerOrganizationChatAnalysisRequestBodyToJSON( + triggerOrganizationChatAnalysisRequestBody: + TriggerOrganizationChatAnalysisRequestBody, +): string { + return JSON.stringify( + TriggerOrganizationChatAnalysisRequestBody$outboundSchema.parse( + triggerOrganizationChatAnalysisRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/components/updateorganizationrequestbody.ts b/client/admin/src/sdk/src/models/components/updateorganizationrequestbody.ts new file mode 100644 index 00000000000..4ee040ebd8d --- /dev/null +++ b/client/admin/src/sdk/src/models/components/updateorganizationrequestbody.ts @@ -0,0 +1,74 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { ClosedEnum } from "../../types/enums.js"; + +/** + * New gram_account_type (free, pro, payg, or enterprise). + */ +export const AccountType = { + Free: "free", + Pro: "pro", + Payg: "payg", + Enterprise: "enterprise", +} as const; +/** + * New gram_account_type (free, pro, payg, or enterprise). + */ +export type AccountType = ClosedEnum; + +export type UpdateOrganizationRequestBody = { + /** + * New gram_account_type (free, pro, payg, or enterprise). + */ + accountType?: AccountType | undefined; + /** + * Organization ID. + */ + id: string; + /** + * New whitelisted flag. + */ + whitelisted?: boolean | undefined; +}; + +/** @internal */ +export const AccountType$outboundSchema: z.ZodMiniEnum = z + .enum(AccountType); + +/** @internal */ +export type UpdateOrganizationRequestBody$Outbound = { + account_type?: string | undefined; + id: string; + whitelisted?: boolean | undefined; +}; + +/** @internal */ +export const UpdateOrganizationRequestBody$outboundSchema: z.ZodMiniType< + UpdateOrganizationRequestBody$Outbound, + UpdateOrganizationRequestBody +> = z.pipe( + z.object({ + accountType: z.optional(AccountType$outboundSchema), + id: z.string(), + whitelisted: z.optional(z.boolean()), + }), + z.transform((v) => { + return remap$(v, { + accountType: "account_type", + }); + }), +); + +export function updateOrganizationRequestBodyToJSON( + updateOrganizationRequestBody: UpdateOrganizationRequestBody, +): string { + return JSON.stringify( + UpdateOrganizationRequestBody$outboundSchema.parse( + updateOrganizationRequestBody, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/errors/apierror.ts b/client/admin/src/sdk/src/models/errors/apierror.ts new file mode 100644 index 00000000000..2e9b865c6a1 --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/apierror.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { GramError } from "./gramerror.js"; + +/** The fallback error class if no more specific error class is matched */ +export class APIError extends GramError { + constructor( + message: string, + httpMeta: { + response: Response; + request: Request; + body: string; + }, + ) { + if (message) { + message += `: `; + } + message += `Status ${httpMeta.response.status}`; + const contentType = httpMeta.response.headers.get("content-type") || `""`; + if (contentType !== "application/json") { + message += ` Content-Type ${ + contentType.includes(" ") ? `"${contentType}"` : contentType + }`; + } + const body = httpMeta.body || `""`; + message += body.length > 100 ? "\n" : ". "; + let bodyDisplay = body; + if (body.length > 10000) { + const truncated = body.substring(0, 10000); + const remaining = body.length - 10000; + bodyDisplay = `${truncated}...and ${remaining} more chars`; + } + message += `Body: ${bodyDisplay}`; + message = message.trim(); + super(message, httpMeta); + this.name = "APIError"; + } +} diff --git a/client/admin/src/sdk/src/models/errors/gramerror.ts b/client/admin/src/sdk/src/models/errors/gramerror.ts new file mode 100644 index 00000000000..2f9ac796542 --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/gramerror.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** The base class for all HTTP error responses */ +export class GramError extends Error { + /** HTTP status code */ + public readonly statusCode: number; + /** HTTP body */ + public readonly body: string; + /** HTTP headers */ + public readonly headers: Headers; + /** HTTP content type */ + public readonly contentType: string; + /** Raw response */ + public readonly rawResponse: Response; + + constructor( + message: string, + httpMeta: { + response: Response; + request: Request; + body: string; + }, + ) { + super(message); + this.statusCode = httpMeta.response.status; + this.body = httpMeta.body; + this.headers = httpMeta.response.headers; + this.contentType = httpMeta.response.headers.get("content-type") || ""; + this.rawResponse = httpMeta.response; + + this.name = "GramError"; + } +} diff --git a/client/admin/src/sdk/src/models/errors/httpclienterrors.ts b/client/admin/src/sdk/src/models/errors/httpclienterrors.ts new file mode 100644 index 00000000000..b34f612124c --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/httpclienterrors.ts @@ -0,0 +1,62 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * Base class for all HTTP errors. + */ +export class HTTPClientError extends Error { + /** The underlying cause of the error. */ + override readonly cause: unknown; + override name = "HTTPClientError"; + constructor(message: string, opts?: { cause?: unknown }) { + let msg = message; + if (opts?.cause) { + msg += `: ${opts.cause}`; + } + + super(msg, opts); + // In older runtimes, the cause field would not have been assigned through + // the super() call. + if (typeof this.cause === "undefined") { + this.cause = opts?.cause; + } + } +} + +/** + * An error to capture unrecognised or unexpected errors when making HTTP calls. + */ +export class UnexpectedClientError extends HTTPClientError { + override name = "UnexpectedClientError"; +} + +/** + * An error that is raised when any inputs used to create a request are invalid. + */ +export class InvalidRequestError extends HTTPClientError { + override name = "InvalidRequestError"; +} + +/** + * An error that is raised when a HTTP request was aborted by the client error. + */ +export class RequestAbortedError extends HTTPClientError { + override readonly name = "RequestAbortedError"; +} + +/** + * An error that is raised when a HTTP request timed out due to an AbortSignal + * signal timeout. + */ +export class RequestTimeoutError extends HTTPClientError { + override readonly name = "RequestTimeoutError"; +} + +/** + * An error that is raised when a HTTP client is unable to make a request to + * a server. + */ +export class ConnectionError extends HTTPClientError { + override readonly name = "ConnectionError"; +} diff --git a/client/admin/src/sdk/src/models/errors/responsevalidationerror.ts b/client/admin/src/sdk/src/models/errors/responsevalidationerror.ts new file mode 100644 index 00000000000..88088afeb79 --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/responsevalidationerror.ts @@ -0,0 +1,50 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4/core"; +import { GramError } from "./gramerror.js"; +import { formatZodError } from "./sdkvalidationerror.js"; + +export class ResponseValidationError extends GramError { + /** + * The raw value that failed validation. + */ + public readonly rawValue: unknown; + + /** + * The raw message that failed validation. + */ + public readonly rawMessage: unknown; + + constructor( + message: string, + extra: { + response: Response; + request: Request; + body: string; + cause: unknown; + rawValue: unknown; + rawMessage: unknown; + }, + ) { + super(message, extra); + this.name = "ResponseValidationError"; + this.cause = extra.cause; + this.rawValue = extra.rawValue; + this.rawMessage = extra.rawMessage; + } + + /** + * Return a pretty-formatted error message if the underlying validation error + * is a ZodError or some other recognized error type, otherwise return the + * default error message. + */ + public pretty(): string { + if (this.cause instanceof z.$ZodError) { + return `${this.rawMessage}\n${formatZodError(this.cause)}`; + } else { + return this.toString(); + } + } +} diff --git a/client/admin/src/sdk/src/models/errors/sdkvalidationerror.ts b/client/admin/src/sdk/src/models/errors/sdkvalidationerror.ts new file mode 100644 index 00000000000..db00022e05d --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/sdkvalidationerror.ts @@ -0,0 +1,54 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4/core"; + +export class SDKValidationError extends Error { + /** + * The raw value that failed validation. + */ + public readonly rawValue: unknown; + + /** + * The raw message that failed validation. + */ + public readonly rawMessage: unknown; + + // Allows for backwards compatibility for `instanceof` checks of `ResponseValidationError` + static override [Symbol.hasInstance]( + instance: unknown, + ): instance is SDKValidationError { + if (!(instance instanceof Error)) return false; + if (!("rawValue" in instance)) return false; + if (!("rawMessage" in instance)) return false; + if (!("pretty" in instance)) return false; + if (typeof instance.pretty !== "function") return false; + return true; + } + + constructor(message: string, cause: unknown, rawValue: unknown) { + super(`${message}: ${cause}`); + this.name = "SDKValidationError"; + this.cause = cause; + this.rawValue = rawValue; + this.rawMessage = message; + } + + /** + * Return a pretty-formatted error message if the underlying validation error + * is a ZodError or some other recognized error type, otherwise return the + * default error message. + */ + public pretty(): string { + if (this.cause instanceof z.$ZodError) { + return `${this.rawMessage}\n${formatZodError(this.cause)}`; + } else { + return this.toString(); + } + } +} + +export function formatZodError(err: z.$ZodError): string { + return z.prettifyError(err); +} diff --git a/client/admin/src/sdk/src/models/errors/serviceerror.ts b/client/admin/src/sdk/src/models/errors/serviceerror.ts new file mode 100644 index 00000000000..38f91193911 --- /dev/null +++ b/client/admin/src/sdk/src/models/errors/serviceerror.ts @@ -0,0 +1,99 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { GramError } from "./gramerror.js"; + +/** + * unauthorized access + */ +export type ServiceErrorData = { + /** + * Is the error a server-side fault? + */ + fault: boolean; + /** + * ID is a unique identifier for this particular occurrence of the problem. + */ + id: string; + /** + * Message is a human-readable explanation specific to this occurrence of the problem. + */ + message: string; + /** + * Name is the name of this class of errors. + */ + name: string; + /** + * Is the error temporary? + */ + temporary: boolean; + /** + * Is the error a timeout? + */ + timeout: boolean; +}; + +/** + * unauthorized access + */ +export class ServiceError extends GramError { + /** + * Is the error a server-side fault? + */ + fault: boolean; + /** + * ID is a unique identifier for this particular occurrence of the problem. + */ + id: string; + /** + * Is the error temporary? + */ + temporary: boolean; + /** + * Is the error a timeout? + */ + timeout: boolean; + + /** The original data that was passed to this error instance. */ + data$: ServiceErrorData; + + constructor( + err: ServiceErrorData, + httpMeta: { response: Response; request: Request; body: string }, + ) { + const message = err.message || `API error occurred: ${JSON.stringify(err)}`; + super(message, httpMeta); + this.data$ = err; + this.fault = err.fault; + this.id = err.id; + this.temporary = err.temporary; + this.timeout = err.timeout; + + this.name = "ServiceError"; + } +} + +/** @internal */ +export const ServiceError$inboundSchema: z.ZodMiniType = + z.pipe( + z.object({ + fault: z.boolean(), + id: z.string(), + message: z.string(), + name: z.string(), + temporary: z.boolean(), + timeout: z.boolean(), + request$: z.custom(x => x instanceof Request), + response$: z.custom(x => x instanceof Response), + body$: z.string(), + }), + z.transform((v) => { + return new ServiceError(v, { + request: v.request$, + response: v.response$, + body: v.body$, + }); + }), + ); diff --git a/client/admin/src/sdk/src/models/operations/admingetinferencekeys.ts b/client/admin/src/sdk/src/models/operations/admingetinferencekeys.ts new file mode 100644 index 00000000000..bdb288d03fc --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetinferencekeys.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetInferenceKeysRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetInferenceKeysRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetInferenceKeysRequest$outboundSchema: z.ZodMiniType< + AdminGetInferenceKeysRequest$Outbound, + AdminGetInferenceKeysRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminGetInferenceKeysRequestToJSON( + adminGetInferenceKeysRequest: AdminGetInferenceKeysRequest, +): string { + return JSON.stringify( + AdminGetInferenceKeysRequest$outboundSchema.parse( + adminGetInferenceKeysRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetinferencespendhistory.ts b/client/admin/src/sdk/src/models/operations/admingetinferencespendhistory.ts new file mode 100644 index 00000000000..14f41fe4284 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetinferencespendhistory.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetInferenceSpendHistoryRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetInferenceSpendHistoryRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetInferenceSpendHistoryRequest$outboundSchema: z.ZodMiniType< + AdminGetInferenceSpendHistoryRequest$Outbound, + AdminGetInferenceSpendHistoryRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminGetInferenceSpendHistoryRequestToJSON( + adminGetInferenceSpendHistoryRequest: AdminGetInferenceSpendHistoryRequest, +): string { + return JSON.stringify( + AdminGetInferenceSpendHistoryRequest$outboundSchema.parse( + adminGetInferenceSpendHistoryRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetorganization.ts b/client/admin/src/sdk/src/models/operations/admingetorganization.ts new file mode 100644 index 00000000000..0d803234220 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetorganization.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetOrganizationRequest = { + /** + * Organization ID or slug. + */ + idOrSlug: string; +}; + +/** @internal */ +export type AdminGetOrganizationRequest$Outbound = { + id_or_slug: string; +}; + +/** @internal */ +export const AdminGetOrganizationRequest$outboundSchema: z.ZodMiniType< + AdminGetOrganizationRequest$Outbound, + AdminGetOrganizationRequest +> = z.pipe( + z.object({ + idOrSlug: z.string(), + }), + z.transform((v) => { + return remap$(v, { + idOrSlug: "id_or_slug", + }); + }), +); + +export function adminGetOrganizationRequestToJSON( + adminGetOrganizationRequest: AdminGetOrganizationRequest, +): string { + return JSON.stringify( + AdminGetOrganizationRequest$outboundSchema.parse( + adminGetOrganizationRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetorganizationchatanalysissettings.ts b/client/admin/src/sdk/src/models/operations/admingetorganizationchatanalysissettings.ts new file mode 100644 index 00000000000..3b9e660faf5 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetorganizationchatanalysissettings.ts @@ -0,0 +1,42 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetOrganizationChatAnalysisSettingsRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetOrganizationChatAnalysisSettingsRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetOrganizationChatAnalysisSettingsRequest$outboundSchema: + z.ZodMiniType< + AdminGetOrganizationChatAnalysisSettingsRequest$Outbound, + AdminGetOrganizationChatAnalysisSettingsRequest + > = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), + ); + +export function adminGetOrganizationChatAnalysisSettingsRequestToJSON( + adminGetOrganizationChatAnalysisSettingsRequest: + AdminGetOrganizationChatAnalysisSettingsRequest, +): string { + return JSON.stringify( + AdminGetOrganizationChatAnalysisSettingsRequest$outboundSchema.parse( + adminGetOrganizationChatAnalysisSettingsRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetorganizationfeatures.ts b/client/admin/src/sdk/src/models/operations/admingetorganizationfeatures.ts new file mode 100644 index 00000000000..71a223e2476 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetorganizationfeatures.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetOrganizationFeaturesRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetOrganizationFeaturesRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetOrganizationFeaturesRequest$outboundSchema: z.ZodMiniType< + AdminGetOrganizationFeaturesRequest$Outbound, + AdminGetOrganizationFeaturesRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminGetOrganizationFeaturesRequestToJSON( + adminGetOrganizationFeaturesRequest: AdminGetOrganizationFeaturesRequest, +): string { + return JSON.stringify( + AdminGetOrganizationFeaturesRequest$outboundSchema.parse( + adminGetOrganizationFeaturesRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetpaygbillingsummary.ts b/client/admin/src/sdk/src/models/operations/admingetpaygbillingsummary.ts new file mode 100644 index 00000000000..73cf647eff7 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetpaygbillingsummary.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetPaygBillingSummaryRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetPaygBillingSummaryRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetPaygBillingSummaryRequest$outboundSchema: z.ZodMiniType< + AdminGetPaygBillingSummaryRequest$Outbound, + AdminGetPaygBillingSummaryRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminGetPaygBillingSummaryRequestToJSON( + adminGetPaygBillingSummaryRequest: AdminGetPaygBillingSummaryRequest, +): string { + return JSON.stringify( + AdminGetPaygBillingSummaryRequest$outboundSchema.parse( + adminGetPaygBillingSummaryRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetproject.ts b/client/admin/src/sdk/src/models/operations/admingetproject.ts new file mode 100644 index 00000000000..4efff5f4b76 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetproject.ts @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetProjectRequest = { + /** + * Project ID or slug. + */ + idOrSlug: string; + /** + * Organization the project must belong to, by id or slug. A project outside it is reported as not found. Optional, because the global project lookup has no organization to scope by. + */ + organizationIdOrSlug?: string | undefined; +}; + +/** @internal */ +export type AdminGetProjectRequest$Outbound = { + id_or_slug: string; + organization_id_or_slug?: string | undefined; +}; + +/** @internal */ +export const AdminGetProjectRequest$outboundSchema: z.ZodMiniType< + AdminGetProjectRequest$Outbound, + AdminGetProjectRequest +> = z.pipe( + z.object({ + idOrSlug: z.string(), + organizationIdOrSlug: z.optional(z.string()), + }), + z.transform((v) => { + return remap$(v, { + idOrSlug: "id_or_slug", + organizationIdOrSlug: "organization_id_or_slug", + }); + }), +); + +export function adminGetProjectRequestToJSON( + adminGetProjectRequest: AdminGetProjectRequest, +): string { + return JSON.stringify( + AdminGetProjectRequest$outboundSchema.parse(adminGetProjectRequest), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/admingetstripesubscription.ts b/client/admin/src/sdk/src/models/operations/admingetstripesubscription.ts new file mode 100644 index 00000000000..e814e7fc10e --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/admingetstripesubscription.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminGetStripeSubscriptionRequest = { + organizationId: string; +}; + +/** @internal */ +export type AdminGetStripeSubscriptionRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminGetStripeSubscriptionRequest$outboundSchema: z.ZodMiniType< + AdminGetStripeSubscriptionRequest$Outbound, + AdminGetStripeSubscriptionRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminGetStripeSubscriptionRequestToJSON( + adminGetStripeSubscriptionRequest: AdminGetStripeSubscriptionRequest, +): string { + return JSON.stringify( + AdminGetStripeSubscriptionRequest$outboundSchema.parse( + adminGetStripeSubscriptionRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/adminlistorganizationactivity.ts b/client/admin/src/sdk/src/models/operations/adminlistorganizationactivity.ts new file mode 100644 index 00000000000..58108243983 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/adminlistorganizationactivity.ts @@ -0,0 +1,86 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { + AdminListOrganizationActivityResult, + AdminListOrganizationActivityResult$inboundSchema, +} from "../components/adminlistorganizationactivityresult.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminListOrganizationActivityRequest = { + /** + * Organization ID. + */ + organizationId: string; + /** + * Cursor for paginating through organization activity. + */ + cursor?: string | undefined; +}; + +export type AdminListOrganizationActivityResponse = { + result: AdminListOrganizationActivityResult; +}; + +/** @internal */ +export type AdminListOrganizationActivityRequest$Outbound = { + organization_id: string; + cursor?: string | undefined; +}; + +/** @internal */ +export const AdminListOrganizationActivityRequest$outboundSchema: z.ZodMiniType< + AdminListOrganizationActivityRequest$Outbound, + AdminListOrganizationActivityRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + cursor: z.optional(z.string()), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminListOrganizationActivityRequestToJSON( + adminListOrganizationActivityRequest: AdminListOrganizationActivityRequest, +): string { + return JSON.stringify( + AdminListOrganizationActivityRequest$outboundSchema.parse( + adminListOrganizationActivityRequest, + ), + ); +} + +/** @internal */ +export const AdminListOrganizationActivityResponse$inboundSchema: z.ZodMiniType< + AdminListOrganizationActivityResponse, + unknown +> = z.pipe( + z.object({ + Result: AdminListOrganizationActivityResult$inboundSchema, + }), + z.transform((v) => { + return remap$(v, { + "Result": "result", + }); + }), +); + +export function adminListOrganizationActivityResponseFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => + AdminListOrganizationActivityResponse$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationActivityResponse' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/models/operations/adminlistorganizationmembers.ts b/client/admin/src/sdk/src/models/operations/adminlistorganizationmembers.ts new file mode 100644 index 00000000000..7c520d7879e --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/adminlistorganizationmembers.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminListOrganizationMembersRequest = { + /** + * Organization ID. + */ + organizationId: string; +}; + +/** @internal */ +export type AdminListOrganizationMembersRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminListOrganizationMembersRequest$outboundSchema: z.ZodMiniType< + AdminListOrganizationMembersRequest$Outbound, + AdminListOrganizationMembersRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminListOrganizationMembersRequestToJSON( + adminListOrganizationMembersRequest: AdminListOrganizationMembersRequest, +): string { + return JSON.stringify( + AdminListOrganizationMembersRequest$outboundSchema.parse( + adminListOrganizationMembersRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/adminlistorganizationprojects.ts b/client/admin/src/sdk/src/models/operations/adminlistorganizationprojects.ts new file mode 100644 index 00000000000..3d071752470 --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/adminlistorganizationprojects.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; + +export type AdminListOrganizationProjectsRequest = { + /** + * Organization ID. + */ + organizationId: string; +}; + +/** @internal */ +export type AdminListOrganizationProjectsRequest$Outbound = { + organization_id: string; +}; + +/** @internal */ +export const AdminListOrganizationProjectsRequest$outboundSchema: z.ZodMiniType< + AdminListOrganizationProjectsRequest$Outbound, + AdminListOrganizationProjectsRequest +> = z.pipe( + z.object({ + organizationId: z.string(), + }), + z.transform((v) => { + return remap$(v, { + organizationId: "organization_id", + }); + }), +); + +export function adminListOrganizationProjectsRequestToJSON( + adminListOrganizationProjectsRequest: AdminListOrganizationProjectsRequest, +): string { + return JSON.stringify( + AdminListOrganizationProjectsRequest$outboundSchema.parse( + adminListOrganizationProjectsRequest, + ), + ); +} diff --git a/client/admin/src/sdk/src/models/operations/adminlistorganizations.ts b/client/admin/src/sdk/src/models/operations/adminlistorganizations.ts new file mode 100644 index 00000000000..d84f5c8b02e --- /dev/null +++ b/client/admin/src/sdk/src/models/operations/adminlistorganizations.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { + AdminListOrganizationsResult, + AdminListOrganizationsResult$inboundSchema, +} from "../components/adminlistorganizationsresult.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type AdminListOrganizationsRequest = { + /** + * Search term, trimmed of surrounding whitespace. Matches name and slug as a case-insensitive substring, with % and _ taken literally, and matches organization id and WorkOS id exactly, ignoring case. An id match also returns an organization that disabled_states or include_disabled would otherwise hide; it still respects account_type, account_types, trial_states and cursor. + */ + q?: string | undefined; + /** + * Filter by a single gram_account_type (e.g. free, pro, payg, enterprise). Superseded by account_types, which it joins as one more member of the same set. + */ + accountType?: string | undefined; + /** + * Match any of these gram_account_type values. Empty matches every account type. A value no organization carries matches nothing rather than failing the request. + */ + accountTypes?: Array | undefined; + /** + * Match any of running, ending_soon, expired, demoted, converted or none. Empty matches every trial state. An unrecognised value matches nothing rather than failing the request. + */ + trialStates?: Array | undefined; + /** + * Match any of active or disabled. Empty falls back to include_disabled. An unrecognised value matches nothing rather than failing the request. + */ + disabledStates?: Array | undefined; + /** + * Include organizations with disabled_at set. Defaults to false. Superseded by disabled_states, which overrides it outright when supplied. + */ + includeDisabled?: boolean | undefined; + /** + * Pagination cursor: id of the last item from the previous page. Ignored when sort or page is supplied. + */ + cursor?: string | undefined; + /** + * Page size (default 50, max 100). + */ + limit?: number | undefined; + /** + * Column to sort by: name, slug, account_type, member_count, created_at, disabled_at or trial_ends_at. Any other value sorts by id. Supplying it selects offset paging. + */ + sort?: string | undefined; + /** + * Sort direction, asc or desc, applied to the column named by sort. Any other value sorts ascending. On its own it does nothing: without sort there is no column to reverse, so it neither reorders the results nor selects offset paging. + */ + direction?: string | undefined; + /** + * 1-based page number for offset paging (default 1). Supplying it selects offset paging. + */ + page?: number | undefined; +}; + +export type AdminListOrganizationsResponse = { + result: AdminListOrganizationsResult; +}; + +/** @internal */ +export type AdminListOrganizationsRequest$Outbound = { + q?: string | undefined; + account_type?: string | undefined; + account_types?: Array | undefined; + trial_states?: Array | undefined; + disabled_states?: Array | undefined; + include_disabled?: boolean | undefined; + cursor?: string | undefined; + limit?: number | undefined; + sort?: string | undefined; + direction?: string | undefined; + page?: number | undefined; +}; + +/** @internal */ +export const AdminListOrganizationsRequest$outboundSchema: z.ZodMiniType< + AdminListOrganizationsRequest$Outbound, + AdminListOrganizationsRequest +> = z.pipe( + z.object({ + q: z.optional(z.string()), + accountType: z.optional(z.string()), + accountTypes: z.optional(z.array(z.string())), + trialStates: z.optional(z.array(z.string())), + disabledStates: z.optional(z.array(z.string())), + includeDisabled: z.optional(z.boolean()), + cursor: z.optional(z.string()), + limit: z.optional(z.int()), + sort: z.optional(z.string()), + direction: z.optional(z.string()), + page: z.optional(z.int()), + }), + z.transform((v) => { + return remap$(v, { + accountType: "account_type", + accountTypes: "account_types", + trialStates: "trial_states", + disabledStates: "disabled_states", + includeDisabled: "include_disabled", + }); + }), +); + +export function adminListOrganizationsRequestToJSON( + adminListOrganizationsRequest: AdminListOrganizationsRequest, +): string { + return JSON.stringify( + AdminListOrganizationsRequest$outboundSchema.parse( + adminListOrganizationsRequest, + ), + ); +} + +/** @internal */ +export const AdminListOrganizationsResponse$inboundSchema: z.ZodMiniType< + AdminListOrganizationsResponse, + unknown +> = z.pipe( + z.object({ + Result: AdminListOrganizationsResult$inboundSchema, + }), + z.transform((v) => { + return remap$(v, { + "Result": "result", + }); + }), +); + +export function adminListOrganizationsResponseFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => AdminListOrganizationsResponse$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'AdminListOrganizationsResponse' from JSON`, + ); +} diff --git a/client/admin/src/sdk/src/react-query/_context.tsx b/client/admin/src/sdk/src/react-query/_context.tsx new file mode 100644 index 00000000000..de44a101570 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/_context.tsx @@ -0,0 +1,22 @@ + +import React from "react"; + +import { GramCore } from "../core.js"; + +const GramContext = React.createContext(null); + +export function GramProvider(props: { client: GramCore, children: React.ReactNode }): React.ReactNode { + return ( + + {props.children} + + ); +} + +export function useGramContext(): GramCore { + const value = React.useContext(GramContext); + if (value === null) { + throw new Error("SDK not initialized. Create an instance of GramCore and pass it to ."); + } + return value; +} diff --git a/client/admin/src/sdk/src/react-query/_types.ts b/client/admin/src/sdk/src/react-query/_types.ts new file mode 100644 index 00000000000..cd2a95549b7 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/_types.ts @@ -0,0 +1,177 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { RequestOptions } from "../lib/sdks.js"; +import { PageIterator } from "../types/operations.js"; + +import type { + DefaultError, + InfiniteData, + InfiniteQueryPageParamsOptions, + OmitKeyof, + QueryKey, + QueryObserverOptions, + SkipToken, + UseMutationOptions, + UseQueryOptions, + UseSuspenseQueryOptions, +} from "@tanstack/react-query"; + +// Reaction to breaking change in 5.80.0 https://github.com/TanStack/query/pull/9224#issuecomment-2934835936 +interface UseInfiniteQueryOptions< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> extends + OmitKeyof< + InfiniteQueryObserverOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + "suspense" + > +{ + /** + * Set this to `false` to unsubscribe this observer from updates to the query cache. + * Defaults to `true`. + */ + subscribed?: boolean; +} + +// Reaction to breaking change in 5.80.0 https://github.com/TanStack/query/pull/9224#issuecomment-2934835936 +interface InfiniteQueryObserverOptions< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> extends + QueryObserverOptions< + TQueryFnData, + TError, + TData, + InfiniteData, + TQueryKey, + TPageParam + >, + InfiniteQueryPageParamsOptions +{ +} + +// Reaction to breaking change in 5.80.0 https://github.com/TanStack/query/pull/9224#issuecomment-2934835936 +interface UseSuspenseInfiniteQueryOptions< + TQueryFnData = unknown, + TError = DefaultError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> extends + OmitKeyof< + UseInfiniteQueryOptions, + "queryFn" | "enabled" | "throwOnError" | "placeholderData" + > +{ + queryFn?: Exclude< + UseInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >["queryFn"], + SkipToken + >; +} +export type TupleToPrefixes = T extends [...infer Prefix, any] + ? TupleToPrefixes | T + : never; + +export type QueryHookOptions = + & Omit< + UseQueryOptions, + "queryKey" | "queryFn" | "select" | keyof RequestOptions + > + & RequestOptions; + +export type SuspenseQueryHookOptions = + & Omit< + UseSuspenseQueryOptions, + "queryKey" | "queryFn" | "select" | keyof RequestOptions + > + & RequestOptions; + +export type InfiniteQueryHookOptions< + Data extends PageIterator, + Err = Error, +> = + & Omit< + UseInfiniteQueryOptions< + Data, + Err, + InfiniteData, + QueryKey, + Data["~next"] + >, + | "queryKey" + | "queryFn" + | "select" + | "getNextPageParam" + | "getPreviousPageParam" + | "initialPageParam" + | keyof RequestOptions + > + & RequestOptions + & { initialPageParam?: Data["~next"] }; + +export type SuspenseInfiniteQueryHookOptions< + Data extends PageIterator, + Err = Error, +> = + & Omit< + UseSuspenseInfiniteQueryOptions< + Data, + Err, + InfiniteData, + QueryKey, + Data["~next"] + >, + | "queryKey" + | "queryFn" + | "select" + | "getNextPageParam" + | "getPreviousPageParam" + | "initialPageParam" + | keyof RequestOptions + > + & RequestOptions + & { initialPageParam?: Data["~next"] }; + +export type MutationHookOptions< + Data = unknown, + Err = Error, + Variables = unknown, +> = + & Omit< + UseMutationOptions, + "mutationKey" | "mutationFn" | keyof RequestOptions + > + & RequestOptions; + +/** + * Removes non-serializable properties (functions and symbols) from a PageIterator for SSR hydration. + * React Server Components cannot serialize functions or Symbol properties across the server/client boundary. + */ +export function pageIteratorToJSON( + page: T, +): T { + const { next: _, ...rest } = page as T & { next?: unknown }; + // Symbol properties are copied by spread but can't be serialized for RSC + delete (rest as Record)[Symbol.asyncIterator]; + return rest as T; +} diff --git a/client/admin/src/sdk/src/react-query/adminBulkUpdateAccountType.ts b/client/admin/src/sdk/src/react-query/adminBulkUpdateAccountType.ts new file mode 100644 index 00000000000..db03c909a08 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminBulkUpdateAccountType.ts @@ -0,0 +1,112 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminBulkUpdateAccountType } from "../funcs/adminBulkUpdateAccountType.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminBulkUpdateAccountTypeResult } from "../models/components/adminbulkupdateaccounttyperesult.js"; +import { BulkUpdateAccountTypeRequestBody } from "../models/components/bulkupdateaccounttyperequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminBulkUpdateAccountTypeMutationVariables = { + request: BulkUpdateAccountTypeRequestBody; + options?: RequestOptions; +}; + +export type AdminBulkUpdateAccountTypeMutationData = + AdminBulkUpdateAccountTypeResult; + +export type AdminBulkUpdateAccountTypeMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * bulkUpdateAccountType admin + * + * @remarks + * Sets one account type on many organizations in a single statement. An ID that matches no organization is reported back rather than failing the batch, so a stale ID costs the operator that row and not the whole call. + */ +export function useAdminBulkUpdateAccountTypeMutation( + options?: MutationHookOptions< + AdminBulkUpdateAccountTypeMutationData, + AdminBulkUpdateAccountTypeMutationError, + AdminBulkUpdateAccountTypeMutationVariables + >, +): UseMutationResult< + AdminBulkUpdateAccountTypeMutationData, + AdminBulkUpdateAccountTypeMutationError, + AdminBulkUpdateAccountTypeMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminBulkUpdateAccountTypeMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminBulkUpdateAccountType(): MutationKey { + return ["@gram/admin-client", "admin", "bulkUpdateAccountType"]; +} + +export function buildAdminBulkUpdateAccountTypeMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminBulkUpdateAccountTypeMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminBulkUpdateAccountType(), + mutationFn: function adminBulkUpdateAccountTypeMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminBulkUpdateAccountType( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminCancelStripeSubscription.ts b/client/admin/src/sdk/src/react-query/adminCancelStripeSubscription.ts new file mode 100644 index 00000000000..89f80d759fc --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminCancelStripeSubscription.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminCancelStripeSubscription } from "../funcs/adminCancelStripeSubscription.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminStripeSubscription } from "../models/components/adminstripesubscription.js"; +import { CancelStripeSubscriptionRequestBody } from "../models/components/cancelstripesubscriptionrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminCancelStripeSubscriptionMutationVariables = { + request: CancelStripeSubscriptionRequestBody; + options?: RequestOptions; +}; + +export type AdminCancelStripeSubscriptionMutationData = AdminStripeSubscription; + +export type AdminCancelStripeSubscriptionMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * cancelStripeSubscription admin + * + * @remarks + * Schedules an organization's PAYG subscription to cancel at period end. + */ +export function useAdminCancelStripeSubscriptionMutation( + options?: MutationHookOptions< + AdminCancelStripeSubscriptionMutationData, + AdminCancelStripeSubscriptionMutationError, + AdminCancelStripeSubscriptionMutationVariables + >, +): UseMutationResult< + AdminCancelStripeSubscriptionMutationData, + AdminCancelStripeSubscriptionMutationError, + AdminCancelStripeSubscriptionMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminCancelStripeSubscriptionMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminCancelStripeSubscription(): MutationKey { + return ["@gram/admin-client", "admin", "cancelStripeSubscription"]; +} + +export function buildAdminCancelStripeSubscriptionMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminCancelStripeSubscriptionMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminCancelStripeSubscription(), + mutationFn: function adminCancelStripeSubscriptionMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminCancelStripeSubscription( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminCreateOrganization.ts b/client/admin/src/sdk/src/react-query/adminCreateOrganization.ts new file mode 100644 index 00000000000..48a797710be --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminCreateOrganization.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminCreateOrganization } from "../funcs/adminCreateOrganization.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { CreateOrganizationRequestBody } from "../models/components/createorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminCreateOrganizationMutationVariables = { + request: CreateOrganizationRequestBody; + options?: RequestOptions; +}; + +export type AdminCreateOrganizationMutationData = AdminOrganization; + +export type AdminCreateOrganizationMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * createOrganization admin + * + * @remarks + * Creates an organization in WorkOS and in Gram, so an operator does not have to leave the admin app for the WorkOS dashboard. The organization starts with no members, is not whitelisted, and gets no trial. Idempotent against the WorkOS organization webhook: the Gram ID is derived from the WorkOS ID, so both writers converge on one row. + */ +export function useAdminCreateOrganizationMutation( + options?: MutationHookOptions< + AdminCreateOrganizationMutationData, + AdminCreateOrganizationMutationError, + AdminCreateOrganizationMutationVariables + >, +): UseMutationResult< + AdminCreateOrganizationMutationData, + AdminCreateOrganizationMutationError, + AdminCreateOrganizationMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminCreateOrganizationMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminCreateOrganization(): MutationKey { + return ["@gram/admin-client", "admin", "createOrganization"]; +} + +export function buildAdminCreateOrganizationMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminCreateOrganizationMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminCreateOrganization(), + mutationFn: function adminCreateOrganizationMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminCreateOrganization( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminDisableOrganization.ts b/client/admin/src/sdk/src/react-query/adminDisableOrganization.ts new file mode 100644 index 00000000000..37eb8e94f40 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminDisableOrganization.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminDisableOrganization } from "../funcs/adminDisableOrganization.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { DisableOrganizationRequestBody } from "../models/components/disableorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminDisableOrganizationMutationVariables = { + request: DisableOrganizationRequestBody; + options?: RequestOptions; +}; + +export type AdminDisableOrganizationMutationData = AdminOrganization; + +export type AdminDisableOrganizationMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * disableOrganization admin + * + * @remarks + * Disables an organization, recording the moment of the action in disabled_at. Idempotent: disabling an already-disabled organization keeps the original timestamp. + */ +export function useAdminDisableOrganizationMutation( + options?: MutationHookOptions< + AdminDisableOrganizationMutationData, + AdminDisableOrganizationMutationError, + AdminDisableOrganizationMutationVariables + >, +): UseMutationResult< + AdminDisableOrganizationMutationData, + AdminDisableOrganizationMutationError, + AdminDisableOrganizationMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminDisableOrganizationMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminDisableOrganization(): MutationKey { + return ["@gram/admin-client", "admin", "disableOrganization"]; +} + +export function buildAdminDisableOrganizationMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminDisableOrganizationMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminDisableOrganization(), + mutationFn: function adminDisableOrganizationMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminDisableOrganization( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminEnableOrganization.ts b/client/admin/src/sdk/src/react-query/adminEnableOrganization.ts new file mode 100644 index 00000000000..f30dc2f7df4 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminEnableOrganization.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminEnableOrganization } from "../funcs/adminEnableOrganization.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { EnableOrganizationRequestBody } from "../models/components/enableorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminEnableOrganizationMutationVariables = { + request: EnableOrganizationRequestBody; + options?: RequestOptions; +}; + +export type AdminEnableOrganizationMutationData = AdminOrganization; + +export type AdminEnableOrganizationMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * enableOrganization admin + * + * @remarks + * Re-enables a disabled organization by clearing disabled_at. Idempotent: an organization that is already active is unaffected. + */ +export function useAdminEnableOrganizationMutation( + options?: MutationHookOptions< + AdminEnableOrganizationMutationData, + AdminEnableOrganizationMutationError, + AdminEnableOrganizationMutationVariables + >, +): UseMutationResult< + AdminEnableOrganizationMutationData, + AdminEnableOrganizationMutationError, + AdminEnableOrganizationMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminEnableOrganizationMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminEnableOrganization(): MutationKey { + return ["@gram/admin-client", "admin", "enableOrganization"]; +} + +export function buildAdminEnableOrganizationMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminEnableOrganizationMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminEnableOrganization(), + mutationFn: function adminEnableOrganizationMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminEnableOrganization( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminExtendTrial.ts b/client/admin/src/sdk/src/react-query/adminExtendTrial.ts new file mode 100644 index 00000000000..db5e0675322 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminExtendTrial.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminExtendTrial } from "../funcs/adminExtendTrial.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { ExtendTrialRequestBody } from "../models/components/extendtrialrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminExtendTrialMutationVariables = { + request: ExtendTrialRequestBody; + options?: RequestOptions; +}; + +export type AdminExtendTrialMutationData = AdminOrganization; + +export type AdminExtendTrialMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * extendTrial admin + * + * @remarks + * Extends a running enterprise trial by adding days to its current end date. Only a running trial can be extended: one that has converted, has been demoted, or has already expired is rejected rather than re-armed. + */ +export function useAdminExtendTrialMutation( + options?: MutationHookOptions< + AdminExtendTrialMutationData, + AdminExtendTrialMutationError, + AdminExtendTrialMutationVariables + >, +): UseMutationResult< + AdminExtendTrialMutationData, + AdminExtendTrialMutationError, + AdminExtendTrialMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminExtendTrialMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminExtendTrial(): MutationKey { + return ["@gram/admin-client", "admin", "extendTrial"]; +} + +export function buildAdminExtendTrialMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminExtendTrialMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminExtendTrial(), + mutationFn: function adminExtendTrialMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminExtendTrial( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.core.ts b/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.core.ts new file mode 100644 index 00000000000..e3447b99a18 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.core.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetInferenceKeys } from "../funcs/adminGetInferenceKeys.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminInferenceKey } from "../models/components/admininferencekey.js"; +import { AdminGetInferenceKeysRequest } from "../models/operations/admingetinferencekeys.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetInferenceKeysQueryData = Array; + +export function prefetchAdminGetInferenceKeys( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetInferenceKeysRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetInferenceKeysQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetInferenceKeysQuery( + client$: GramCore, + request: AdminGetInferenceKeysRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetInferenceKeys({ + organizationId: request.organizationId, + }), + queryFn: async function adminGetInferenceKeysQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetInferenceKeys( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetInferenceKeys( + parameters: { organizationId: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "getInferenceKeys", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.ts b/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.ts new file mode 100644 index 00000000000..0cd3152dd07 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetInferenceKeys.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetInferenceKeysRequest } from "../models/operations/admingetinferencekeys.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetInferenceKeysQueryData, + buildAdminGetInferenceKeysQuery, + prefetchAdminGetInferenceKeys, + queryKeyAdminGetInferenceKeys, +} from "./adminGetInferenceKeys.core.js"; +export { + type AdminGetInferenceKeysQueryData, + buildAdminGetInferenceKeysQuery, + prefetchAdminGetInferenceKeys, + queryKeyAdminGetInferenceKeys, +}; + +export type AdminGetInferenceKeysQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getInferenceKeys admin + * + * @remarks + * Returns the configured state of every materialized platform-managed OpenRouter key for an organization. + */ +export function useAdminGetInferenceKeys( + request: AdminGetInferenceKeysRequest, + options?: QueryHookOptions< + AdminGetInferenceKeysQueryData, + AdminGetInferenceKeysQueryError + >, +): UseQueryResult< + AdminGetInferenceKeysQueryData, + AdminGetInferenceKeysQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetInferenceKeysQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getInferenceKeys admin + * + * @remarks + * Returns the configured state of every materialized platform-managed OpenRouter key for an organization. + */ +export function useAdminGetInferenceKeysSuspense( + request: AdminGetInferenceKeysRequest, + options?: SuspenseQueryHookOptions< + AdminGetInferenceKeysQueryData, + AdminGetInferenceKeysQueryError + >, +): UseSuspenseQueryResult< + AdminGetInferenceKeysQueryData, + AdminGetInferenceKeysQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetInferenceKeysQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetInferenceKeysData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminGetInferenceKeysQueryData, +): AdminGetInferenceKeysQueryData | undefined { + const key = queryKeyAdminGetInferenceKeys(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetInferenceKeys( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getInferenceKeys", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetInferenceKeys( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getInferenceKeys"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.core.ts b/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.core.ts new file mode 100644 index 00000000000..fec9394cad0 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.core.ts @@ -0,0 +1,82 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetInferenceSpendHistory } from "../funcs/adminGetInferenceSpendHistory.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminInferenceSpendMonth } from "../models/components/admininferencespendmonth.js"; +import { AdminGetInferenceSpendHistoryRequest } from "../models/operations/admingetinferencespendhistory.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetInferenceSpendHistoryQueryData = Array< + AdminInferenceSpendMonth +>; + +export function prefetchAdminGetInferenceSpendHistory( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetInferenceSpendHistoryRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetInferenceSpendHistoryQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetInferenceSpendHistoryQuery( + client$: GramCore, + request: AdminGetInferenceSpendHistoryRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetInferenceSpendHistory({ + organizationId: request.organizationId, + }), + queryFn: async function adminGetInferenceSpendHistoryQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetInferenceSpendHistory( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetInferenceSpendHistory( + parameters: { organizationId: string }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "getInferenceSpendHistory", + parameters, + ]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.ts b/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.ts new file mode 100644 index 00000000000..f1bc441d09c --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetInferenceSpendHistory.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetInferenceSpendHistoryRequest } from "../models/operations/admingetinferencespendhistory.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetInferenceSpendHistoryQueryData, + buildAdminGetInferenceSpendHistoryQuery, + prefetchAdminGetInferenceSpendHistory, + queryKeyAdminGetInferenceSpendHistory, +} from "./adminGetInferenceSpendHistory.core.js"; +export { + type AdminGetInferenceSpendHistoryQueryData, + buildAdminGetInferenceSpendHistoryQuery, + prefetchAdminGetInferenceSpendHistory, + queryKeyAdminGetInferenceSpendHistory, +}; + +export type AdminGetInferenceSpendHistoryQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getInferenceSpendHistory admin + * + * @remarks + * Returns up to twelve complete UTC calendar months of recorded inference spend for an organization. + */ +export function useAdminGetInferenceSpendHistory( + request: AdminGetInferenceSpendHistoryRequest, + options?: QueryHookOptions< + AdminGetInferenceSpendHistoryQueryData, + AdminGetInferenceSpendHistoryQueryError + >, +): UseQueryResult< + AdminGetInferenceSpendHistoryQueryData, + AdminGetInferenceSpendHistoryQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetInferenceSpendHistoryQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getInferenceSpendHistory admin + * + * @remarks + * Returns up to twelve complete UTC calendar months of recorded inference spend for an organization. + */ +export function useAdminGetInferenceSpendHistorySuspense( + request: AdminGetInferenceSpendHistoryRequest, + options?: SuspenseQueryHookOptions< + AdminGetInferenceSpendHistoryQueryData, + AdminGetInferenceSpendHistoryQueryError + >, +): UseSuspenseQueryResult< + AdminGetInferenceSpendHistoryQueryData, + AdminGetInferenceSpendHistoryQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetInferenceSpendHistoryQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetInferenceSpendHistoryData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminGetInferenceSpendHistoryQueryData, +): AdminGetInferenceSpendHistoryQueryData | undefined { + const key = queryKeyAdminGetInferenceSpendHistory(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetInferenceSpendHistory( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getInferenceSpendHistory", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetInferenceSpendHistory( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getInferenceSpendHistory"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganization.core.ts b/client/admin/src/sdk/src/react-query/adminGetOrganization.core.ts new file mode 100644 index 00000000000..377fcc69b7c --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganization.core.ts @@ -0,0 +1,73 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetOrganization } from "../funcs/adminGetOrganization.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { AdminGetOrganizationRequest } from "../models/operations/admingetorganization.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetOrganizationQueryData = AdminOrganization; + +export function prefetchAdminGetOrganization( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetOrganizationRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetOrganizationQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetOrganizationQuery( + client$: GramCore, + request: AdminGetOrganizationRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetOrganization({ idOrSlug: request.idOrSlug }), + queryFn: async function adminGetOrganizationQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetOrganization( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetOrganization( + parameters: { idOrSlug: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "getOrganization", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganization.ts b/client/admin/src/sdk/src/react-query/adminGetOrganization.ts new file mode 100644 index 00000000000..3e68b1acc6f --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganization.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetOrganizationRequest } from "../models/operations/admingetorganization.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetOrganizationQueryData, + buildAdminGetOrganizationQuery, + prefetchAdminGetOrganization, + queryKeyAdminGetOrganization, +} from "./adminGetOrganization.core.js"; +export { + type AdminGetOrganizationQueryData, + buildAdminGetOrganizationQuery, + prefetchAdminGetOrganization, + queryKeyAdminGetOrganization, +}; + +export type AdminGetOrganizationQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getOrganization admin + * + * @remarks + * Returns full admin details for a single organization by id or slug. + */ +export function useAdminGetOrganization( + request: AdminGetOrganizationRequest, + options?: QueryHookOptions< + AdminGetOrganizationQueryData, + AdminGetOrganizationQueryError + >, +): UseQueryResult< + AdminGetOrganizationQueryData, + AdminGetOrganizationQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetOrganizationQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getOrganization admin + * + * @remarks + * Returns full admin details for a single organization by id or slug. + */ +export function useAdminGetOrganizationSuspense( + request: AdminGetOrganizationRequest, + options?: SuspenseQueryHookOptions< + AdminGetOrganizationQueryData, + AdminGetOrganizationQueryError + >, +): UseSuspenseQueryResult< + AdminGetOrganizationQueryData, + AdminGetOrganizationQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetOrganizationQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetOrganizationData( + client: QueryClient, + queryKeyBase: [parameters: { idOrSlug: string }], + data: AdminGetOrganizationQueryData, +): AdminGetOrganizationQueryData | undefined { + const key = queryKeyAdminGetOrganization(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetOrganization( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { idOrSlug: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getOrganization", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetOrganization( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getOrganization"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.core.ts b/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.core.ts new file mode 100644 index 00000000000..2581903e49e --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.core.ts @@ -0,0 +1,81 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetOrganizationChatAnalysisSettings } from "../funcs/adminGetOrganizationChatAnalysisSettings.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminChatAnalysisSettings } from "../models/components/adminchatanalysissettings.js"; +import { AdminGetOrganizationChatAnalysisSettingsRequest } from "../models/operations/admingetorganizationchatanalysissettings.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetOrganizationChatAnalysisSettingsQueryData = + AdminChatAnalysisSettings; + +export function prefetchAdminGetOrganizationChatAnalysisSettings( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetOrganizationChatAnalysisSettingsQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetOrganizationChatAnalysisSettingsQuery( + client$: GramCore, + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetOrganizationChatAnalysisSettings({ + organizationId: request.organizationId, + }), + queryFn: async function adminGetOrganizationChatAnalysisSettingsQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetOrganizationChatAnalysisSettings( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetOrganizationChatAnalysisSettings( + parameters: { organizationId: string }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "getOrganizationChatAnalysisSettings", + parameters, + ]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.ts b/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.ts new file mode 100644 index 00000000000..896a478e059 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganizationChatAnalysisSettings.ts @@ -0,0 +1,144 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetOrganizationChatAnalysisSettingsRequest } from "../models/operations/admingetorganizationchatanalysissettings.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetOrganizationChatAnalysisSettingsQueryData, + buildAdminGetOrganizationChatAnalysisSettingsQuery, + prefetchAdminGetOrganizationChatAnalysisSettings, + queryKeyAdminGetOrganizationChatAnalysisSettings, +} from "./adminGetOrganizationChatAnalysisSettings.core.js"; +export { + type AdminGetOrganizationChatAnalysisSettingsQueryData, + buildAdminGetOrganizationChatAnalysisSettingsQuery, + prefetchAdminGetOrganizationChatAnalysisSettings, + queryKeyAdminGetOrganizationChatAnalysisSettings, +}; + +export type AdminGetOrganizationChatAnalysisSettingsQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getOrganizationChatAnalysisSettings admin + */ +export function useAdminGetOrganizationChatAnalysisSettings( + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: QueryHookOptions< + AdminGetOrganizationChatAnalysisSettingsQueryData, + AdminGetOrganizationChatAnalysisSettingsQueryError + >, +): UseQueryResult< + AdminGetOrganizationChatAnalysisSettingsQueryData, + AdminGetOrganizationChatAnalysisSettingsQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetOrganizationChatAnalysisSettingsQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getOrganizationChatAnalysisSettings admin + */ +export function useAdminGetOrganizationChatAnalysisSettingsSuspense( + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: SuspenseQueryHookOptions< + AdminGetOrganizationChatAnalysisSettingsQueryData, + AdminGetOrganizationChatAnalysisSettingsQueryError + >, +): UseSuspenseQueryResult< + AdminGetOrganizationChatAnalysisSettingsQueryData, + AdminGetOrganizationChatAnalysisSettingsQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetOrganizationChatAnalysisSettingsQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetOrganizationChatAnalysisSettingsData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminGetOrganizationChatAnalysisSettingsQueryData, +): AdminGetOrganizationChatAnalysisSettingsQueryData | undefined { + const key = queryKeyAdminGetOrganizationChatAnalysisSettings(...queryKeyBase); + + return client.setQueryData( + key, + data, + ); +} + +export function invalidateAdminGetOrganizationChatAnalysisSettings( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getOrganizationChatAnalysisSettings", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetOrganizationChatAnalysisSettings( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getOrganizationChatAnalysisSettings", + ], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.core.ts b/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.core.ts new file mode 100644 index 00000000000..b2d80dc8696 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.core.ts @@ -0,0 +1,66 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetOrganizationStats } from "../funcs/adminGetOrganizationStats.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganizationStats } from "../models/components/adminorganizationstats.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetOrganizationStatsQueryData = AdminOrganizationStats; + +export function prefetchAdminGetOrganizationStats( + queryClient: QueryClient, + client$: GramCore, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetOrganizationStatsQuery( + client$, + options, + ), + }); +} + +export function buildAdminGetOrganizationStatsQuery( + client$: GramCore, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetOrganizationStats(), + queryFn: async function adminGetOrganizationStatsQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetOrganizationStats( + client$, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetOrganizationStats(): QueryKey { + return ["@gram/admin-client", "admin", "getOrganizationStats"]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.ts b/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.ts new file mode 100644 index 00000000000..4c28bd07ac5 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetOrganizationStats.ts @@ -0,0 +1,117 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { useGramContext } from "./_context.js"; +import { QueryHookOptions, SuspenseQueryHookOptions } from "./_types.js"; +import { + AdminGetOrganizationStatsQueryData, + buildAdminGetOrganizationStatsQuery, + prefetchAdminGetOrganizationStats, + queryKeyAdminGetOrganizationStats, +} from "./adminGetOrganizationStats.core.js"; +export { + type AdminGetOrganizationStatsQueryData, + buildAdminGetOrganizationStatsQuery, + prefetchAdminGetOrganizationStats, + queryKeyAdminGetOrganizationStats, +}; + +export type AdminGetOrganizationStatsQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getOrganizationStats admin + * + * @remarks + * Returns platform-wide organization counts for the strip above the organizations list. Every figure counts the whole platform: none of them narrows to the caller's list filters, so the strip does not move when an operator filters. + */ +export function useAdminGetOrganizationStats( + options?: QueryHookOptions< + AdminGetOrganizationStatsQueryData, + AdminGetOrganizationStatsQueryError + >, +): UseQueryResult< + AdminGetOrganizationStatsQueryData, + AdminGetOrganizationStatsQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetOrganizationStatsQuery( + client, + options, + ), + ...options, + }); +} + +/** + * getOrganizationStats admin + * + * @remarks + * Returns platform-wide organization counts for the strip above the organizations list. Every figure counts the whole platform: none of them narrows to the caller's list filters, so the strip does not move when an operator filters. + */ +export function useAdminGetOrganizationStatsSuspense( + options?: SuspenseQueryHookOptions< + AdminGetOrganizationStatsQueryData, + AdminGetOrganizationStatsQueryError + >, +): UseSuspenseQueryResult< + AdminGetOrganizationStatsQueryData, + AdminGetOrganizationStatsQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetOrganizationStatsQuery( + client, + options, + ), + ...options, + }); +} + +export function setAdminGetOrganizationStatsData( + client: QueryClient, + data: AdminGetOrganizationStatsQueryData, +): AdminGetOrganizationStatsQueryData | undefined { + const key = queryKeyAdminGetOrganizationStats(); + + return client.setQueryData(key, data); +} + +export function invalidateAllAdminGetOrganizationStats( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getOrganizationStats"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.core.ts b/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.core.ts new file mode 100644 index 00000000000..bb18d082100 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.core.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetPaygBillingSummary } from "../funcs/adminGetPaygBillingSummary.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminPaygBillingSummary } from "../models/components/adminpaygbillingsummary.js"; +import { AdminGetPaygBillingSummaryRequest } from "../models/operations/admingetpaygbillingsummary.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetPaygBillingSummaryQueryData = AdminPaygBillingSummary; + +export function prefetchAdminGetPaygBillingSummary( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetPaygBillingSummaryRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetPaygBillingSummaryQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetPaygBillingSummaryQuery( + client$: GramCore, + request: AdminGetPaygBillingSummaryRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetPaygBillingSummary({ + organizationId: request.organizationId, + }), + queryFn: async function adminGetPaygBillingSummaryQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetPaygBillingSummary( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetPaygBillingSummary( + parameters: { organizationId: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "getPaygBillingSummary", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.ts b/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.ts new file mode 100644 index 00000000000..a0fc50e18d0 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetPaygBillingSummary.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetPaygBillingSummaryRequest } from "../models/operations/admingetpaygbillingsummary.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetPaygBillingSummaryQueryData, + buildAdminGetPaygBillingSummaryQuery, + prefetchAdminGetPaygBillingSummary, + queryKeyAdminGetPaygBillingSummary, +} from "./adminGetPaygBillingSummary.core.js"; +export { + type AdminGetPaygBillingSummaryQueryData, + buildAdminGetPaygBillingSummaryQuery, + prefetchAdminGetPaygBillingSummary, + queryKeyAdminGetPaygBillingSummary, +}; + +export type AdminGetPaygBillingSummaryQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getPaygBillingSummary admin + * + * @remarks + * Returns current PAYG usage and estimated cost for an organization. + */ +export function useAdminGetPaygBillingSummary( + request: AdminGetPaygBillingSummaryRequest, + options?: QueryHookOptions< + AdminGetPaygBillingSummaryQueryData, + AdminGetPaygBillingSummaryQueryError + >, +): UseQueryResult< + AdminGetPaygBillingSummaryQueryData, + AdminGetPaygBillingSummaryQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetPaygBillingSummaryQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getPaygBillingSummary admin + * + * @remarks + * Returns current PAYG usage and estimated cost for an organization. + */ +export function useAdminGetPaygBillingSummarySuspense( + request: AdminGetPaygBillingSummaryRequest, + options?: SuspenseQueryHookOptions< + AdminGetPaygBillingSummaryQueryData, + AdminGetPaygBillingSummaryQueryError + >, +): UseSuspenseQueryResult< + AdminGetPaygBillingSummaryQueryData, + AdminGetPaygBillingSummaryQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetPaygBillingSummaryQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetPaygBillingSummaryData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminGetPaygBillingSummaryQueryData, +): AdminGetPaygBillingSummaryQueryData | undefined { + const key = queryKeyAdminGetPaygBillingSummary(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetPaygBillingSummary( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getPaygBillingSummary", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetPaygBillingSummary( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getPaygBillingSummary"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetProject.core.ts b/client/admin/src/sdk/src/react-query/adminGetProject.core.ts new file mode 100644 index 00000000000..d88b8a29a9b --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetProject.core.ts @@ -0,0 +1,74 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetProject } from "../funcs/adminGetProject.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminProjectDetail } from "../models/components/adminprojectdetail.js"; +import { AdminGetProjectRequest } from "../models/operations/admingetproject.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetProjectQueryData = AdminProjectDetail; + +export function prefetchAdminGetProject( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetProjectRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetProjectQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetProjectQuery( + client$: GramCore, + request: AdminGetProjectRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: (context: QueryFunctionContext) => Promise; +} { + return { + queryKey: queryKeyAdminGetProject({ + idOrSlug: request.idOrSlug, + organizationIdOrSlug: request.organizationIdOrSlug, + }), + queryFn: async function adminGetProjectQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetProject( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetProject( + parameters: { idOrSlug: string; organizationIdOrSlug?: string | undefined }, +): QueryKey { + return ["@gram/admin-client", "admin", "getProject", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetProject.ts b/client/admin/src/sdk/src/react-query/adminGetProject.ts new file mode 100644 index 00000000000..f01df6dcc24 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetProject.ts @@ -0,0 +1,139 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetProjectRequest } from "../models/operations/admingetproject.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetProjectQueryData, + buildAdminGetProjectQuery, + prefetchAdminGetProject, + queryKeyAdminGetProject, +} from "./adminGetProject.core.js"; +export { + type AdminGetProjectQueryData, + buildAdminGetProjectQuery, + prefetchAdminGetProject, + queryKeyAdminGetProject, +}; + +export type AdminGetProjectQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getProject admin + * + * @remarks + * Returns full admin details for a project by id or slug, including aggregated counts of child resources. + */ +export function useAdminGetProject( + request: AdminGetProjectRequest, + options?: QueryHookOptions< + AdminGetProjectQueryData, + AdminGetProjectQueryError + >, +): UseQueryResult { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetProjectQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getProject admin + * + * @remarks + * Returns full admin details for a project by id or slug, including aggregated counts of child resources. + */ +export function useAdminGetProjectSuspense( + request: AdminGetProjectRequest, + options?: SuspenseQueryHookOptions< + AdminGetProjectQueryData, + AdminGetProjectQueryError + >, +): UseSuspenseQueryResult { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetProjectQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetProjectData( + client: QueryClient, + queryKeyBase: [ + parameters: { idOrSlug: string; organizationIdOrSlug?: string | undefined }, + ], + data: AdminGetProjectQueryData, +): AdminGetProjectQueryData | undefined { + const key = queryKeyAdminGetProject(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetProject( + client: QueryClient, + queryKeyBase: TupleToPrefixes< + [parameters: { + idOrSlug: string; + organizationIdOrSlug?: string | undefined; + }] + >, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getProject", ...queryKeyBase], + }); +} + +export function invalidateAllAdminGetProject( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getProject"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetSession.core.ts b/client/admin/src/sdk/src/react-query/adminGetSession.core.ts new file mode 100644 index 00000000000..b06a76e73fd --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetSession.core.ts @@ -0,0 +1,64 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetSession } from "../funcs/adminGetSession.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminSession } from "../models/components/adminsession.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetSessionQueryData = AdminSession; + +export function prefetchAdminGetSession( + queryClient: QueryClient, + client$: GramCore, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetSessionQuery( + client$, + options, + ), + }); +} + +export function buildAdminGetSessionQuery( + client$: GramCore, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: (context: QueryFunctionContext) => Promise; +} { + return { + queryKey: queryKeyAdminGetSession(), + queryFn: async function adminGetSessionQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetSession( + client$, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetSession(): QueryKey { + return ["@gram/admin-client", "admin", "getSession"]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetSession.ts b/client/admin/src/sdk/src/react-query/adminGetSession.ts new file mode 100644 index 00000000000..84f0ac83e7b --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetSession.ts @@ -0,0 +1,105 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { useGramContext } from "./_context.js"; +import { QueryHookOptions, SuspenseQueryHookOptions } from "./_types.js"; +import { + AdminGetSessionQueryData, + buildAdminGetSessionQuery, + prefetchAdminGetSession, + queryKeyAdminGetSession, +} from "./adminGetSession.core.js"; +export { + type AdminGetSessionQueryData, + buildAdminGetSessionQuery, + prefetchAdminGetSession, + queryKeyAdminGetSession, +}; + +export type AdminGetSessionQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getSession admin + */ +export function useAdminGetSession( + options?: QueryHookOptions< + AdminGetSessionQueryData, + AdminGetSessionQueryError + >, +): UseQueryResult { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetSessionQuery( + client, + options, + ), + ...options, + }); +} + +/** + * getSession admin + */ +export function useAdminGetSessionSuspense( + options?: SuspenseQueryHookOptions< + AdminGetSessionQueryData, + AdminGetSessionQueryError + >, +): UseSuspenseQueryResult { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetSessionQuery( + client, + options, + ), + ...options, + }); +} + +export function setAdminGetSessionData( + client: QueryClient, + data: AdminGetSessionQueryData, +): AdminGetSessionQueryData | undefined { + const key = queryKeyAdminGetSession(); + + return client.setQueryData(key, data); +} + +export function invalidateAllAdminGetSession( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getSession"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.core.ts b/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.core.ts new file mode 100644 index 00000000000..c72b0c3a892 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.core.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetStripeSubscription } from "../funcs/adminGetStripeSubscription.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminStripeSubscription } from "../models/components/adminstripesubscription.js"; +import { AdminGetStripeSubscriptionRequest } from "../models/operations/admingetstripesubscription.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminGetStripeSubscriptionQueryData = AdminStripeSubscription; + +export function prefetchAdminGetStripeSubscription( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetStripeSubscriptionRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminGetStripeSubscriptionQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminGetStripeSubscriptionQuery( + client$: GramCore, + request: AdminGetStripeSubscriptionRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminGetStripeSubscription({ + organizationId: request.organizationId, + }), + queryFn: async function adminGetStripeSubscriptionQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetStripeSubscription( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminGetStripeSubscription( + parameters: { organizationId: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "getStripeSubscription", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.ts b/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.ts new file mode 100644 index 00000000000..9526a280212 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminGetStripeSubscription.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetStripeSubscriptionRequest } from "../models/operations/admingetstripesubscription.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminGetStripeSubscriptionQueryData, + buildAdminGetStripeSubscriptionQuery, + prefetchAdminGetStripeSubscription, + queryKeyAdminGetStripeSubscription, +} from "./adminGetStripeSubscription.core.js"; +export { + type AdminGetStripeSubscriptionQueryData, + buildAdminGetStripeSubscriptionQuery, + prefetchAdminGetStripeSubscription, + queryKeyAdminGetStripeSubscription, +}; + +export type AdminGetStripeSubscriptionQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getStripeSubscription admin + * + * @remarks + * Returns the live Stripe subscription and payment state for an organization. + */ +export function useAdminGetStripeSubscription( + request: AdminGetStripeSubscriptionRequest, + options?: QueryHookOptions< + AdminGetStripeSubscriptionQueryData, + AdminGetStripeSubscriptionQueryError + >, +): UseQueryResult< + AdminGetStripeSubscriptionQueryData, + AdminGetStripeSubscriptionQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminGetStripeSubscriptionQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getStripeSubscription admin + * + * @remarks + * Returns the live Stripe subscription and payment state for an organization. + */ +export function useAdminGetStripeSubscriptionSuspense( + request: AdminGetStripeSubscriptionRequest, + options?: SuspenseQueryHookOptions< + AdminGetStripeSubscriptionQueryData, + AdminGetStripeSubscriptionQueryError + >, +): UseSuspenseQueryResult< + AdminGetStripeSubscriptionQueryData, + AdminGetStripeSubscriptionQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminGetStripeSubscriptionQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminGetStripeSubscriptionData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminGetStripeSubscriptionQueryData, +): AdminGetStripeSubscriptionQueryData | undefined { + const key = queryKeyAdminGetStripeSubscription(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminGetStripeSubscription( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getStripeSubscription", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminGetStripeSubscription( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getStripeSubscription"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.core.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.core.ts new file mode 100644 index 00000000000..ddf4bd73519 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.core.ts @@ -0,0 +1,179 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminListOrganizationActivity } from "../funcs/adminListOrganizationActivity.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { + AdminListOrganizationActivityRequest, + AdminListOrganizationActivityResponse, +} from "../models/operations/adminlistorganizationactivity.js"; +import { unwrapAsync } from "../types/fp.js"; +import { PageIterator, unwrapResultIterator } from "../types/operations.js"; +import { pageIteratorToJSON } from "./_types.js"; +export type AdminListOrganizationActivityQueryData = + AdminListOrganizationActivityResponse; + +export type AdminListOrganizationActivityInfiniteQueryData = PageIterator< + AdminListOrganizationActivityResponse, + { cursor: string } +>; + +export type AdminListOrganizationActivityPageParams = PageIterator< + AdminListOrganizationActivityResponse, + { cursor: string } +>["~next"]; + +export function prefetchAdminListOrganizationActivity( + queryClient: QueryClient, + client$: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminListOrganizationActivityQuery( + client$, + request, + options, + ), + }); +} + +export function prefetchAdminListOrganizationActivityInfinite( + queryClient: QueryClient, + client$: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchInfiniteQuery({ + ...buildAdminListOrganizationActivityInfiniteQuery( + client$, + request, + options, + ), + initialPageParam: undefined as AdminListOrganizationActivityPageParams, + getNextPageParam: ( + previousPage: AdminListOrganizationActivityInfiniteQueryData, + ) => previousPage["~next"], + }); +} + +export function buildAdminListOrganizationActivityQuery( + client$: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizationActivity({ + organizationId: request.organizationId, + cursor: request.cursor, + }), + queryFn: async function adminListOrganizationActivityQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminListOrganizationActivity( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function buildAdminListOrganizationActivityInfiniteQuery( + client$: GramCore, + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext< + QueryKey, + AdminListOrganizationActivityPageParams + >, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizationActivityInfinite({ + organizationId: request.organizationId, + cursor: request.cursor, + }), + queryFn: async function adminListOrganizationActivityQuery( + ctx, + ): Promise { + const sig = combineSignals(ctx.signal, options?.fetchOptions?.signal); + const mergedOptions = { + ...options, + fetchOptions: { ...options?.fetchOptions, signal: sig }, + }; + + if (!ctx.pageParam) { + const pageResult = await unwrapResultIterator( + adminListOrganizationActivity( + client$, + request, + mergedOptions, + ), + ); + return pageIteratorToJSON(pageResult); + } + const pageResult = await unwrapResultIterator( + adminListOrganizationActivity( + client$, + { + ...request, + cursor: ctx.pageParam.cursor, + }, + mergedOptions, + ), + ); + return pageIteratorToJSON(pageResult); + }, + }; +} + +export function queryKeyAdminListOrganizationActivity( + parameters: { organizationId: string; cursor?: string | undefined }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "listOrganizationActivity", + parameters, + ]; +} + +export function queryKeyAdminListOrganizationActivityInfinite( + parameters: { organizationId: string; cursor?: string | undefined }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "listOrganizationActivity", + "infinite", + parameters, + ]; +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.ts new file mode 100644 index 00000000000..6715a989a09 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationActivity.ts @@ -0,0 +1,247 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InfiniteData, + InvalidateQueryFilters, + QueryClient, + QueryKey, + useInfiniteQuery, + UseInfiniteQueryResult, + useQuery, + UseQueryResult, + useSuspenseInfiniteQuery, + UseSuspenseInfiniteQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminListOrganizationActivityRequest } from "../models/operations/adminlistorganizationactivity.js"; +import { useGramContext } from "./_context.js"; +import { + InfiniteQueryHookOptions, + QueryHookOptions, + SuspenseInfiniteQueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityPageParams, + AdminListOrganizationActivityQueryData, + buildAdminListOrganizationActivityInfiniteQuery, + buildAdminListOrganizationActivityQuery, + prefetchAdminListOrganizationActivity, + prefetchAdminListOrganizationActivityInfinite, + queryKeyAdminListOrganizationActivity, + queryKeyAdminListOrganizationActivityInfinite, +} from "./adminListOrganizationActivity.core.js"; +export { + type AdminListOrganizationActivityInfiniteQueryData, + type AdminListOrganizationActivityPageParams, + type AdminListOrganizationActivityQueryData, + buildAdminListOrganizationActivityInfiniteQuery, + buildAdminListOrganizationActivityQuery, + prefetchAdminListOrganizationActivity, + prefetchAdminListOrganizationActivityInfinite, + queryKeyAdminListOrganizationActivity, + queryKeyAdminListOrganizationActivityInfinite, +}; + +export type AdminListOrganizationActivityQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ +export function useAdminListOrganizationActivity( + request: AdminListOrganizationActivityRequest, + options?: QueryHookOptions< + AdminListOrganizationActivityQueryData, + AdminListOrganizationActivityQueryError + >, +): UseQueryResult< + AdminListOrganizationActivityQueryData, + AdminListOrganizationActivityQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminListOrganizationActivityQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ +export function useAdminListOrganizationActivitySuspense( + request: AdminListOrganizationActivityRequest, + options?: SuspenseQueryHookOptions< + AdminListOrganizationActivityQueryData, + AdminListOrganizationActivityQueryError + >, +): UseSuspenseQueryResult< + AdminListOrganizationActivityQueryData, + AdminListOrganizationActivityQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminListOrganizationActivityQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ +export function useAdminListOrganizationActivityInfinite( + request: AdminListOrganizationActivityRequest, + options?: InfiniteQueryHookOptions< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityQueryError + >, +): UseInfiniteQueryResult< + InfiniteData< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityPageParams + >, + AdminListOrganizationActivityQueryError +> { + const client = useGramContext(); + return useInfiniteQuery< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityQueryError, + InfiniteData< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityPageParams + >, + QueryKey, + AdminListOrganizationActivityPageParams + >({ + ...buildAdminListOrganizationActivityInfiniteQuery( + client, + request, + options, + ), + initialPageParam: options?.initialPageParam, + getNextPageParam: (previousPage) => previousPage["~next"], + ...options, + }); +} + +/** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ +export function useAdminListOrganizationActivityInfiniteSuspense( + request: AdminListOrganizationActivityRequest, + options?: SuspenseInfiniteQueryHookOptions< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityQueryError + >, +): UseSuspenseInfiniteQueryResult< + InfiniteData< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityPageParams + >, + AdminListOrganizationActivityQueryError +> { + const client = useGramContext(); + return useSuspenseInfiniteQuery< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityQueryError, + InfiniteData< + AdminListOrganizationActivityInfiniteQueryData, + AdminListOrganizationActivityPageParams + >, + QueryKey, + AdminListOrganizationActivityPageParams + >({ + ...buildAdminListOrganizationActivityInfiniteQuery( + client, + request, + options, + ), + initialPageParam: options?.initialPageParam, + getNextPageParam: (previousPage) => previousPage["~next"], + ...options, + }); +} + +export function setAdminListOrganizationActivityData( + client: QueryClient, + queryKeyBase: [ + parameters: { organizationId: string; cursor?: string | undefined }, + ], + data: AdminListOrganizationActivityQueryData, +): AdminListOrganizationActivityQueryData | undefined { + const key = queryKeyAdminListOrganizationActivity(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminListOrganizationActivity( + client: QueryClient, + queryKeyBase: TupleToPrefixes< + [parameters: { organizationId: string; cursor?: string | undefined }] + >, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "listOrganizationActivity", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminListOrganizationActivity( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "listOrganizationActivity"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.core.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.core.ts new file mode 100644 index 00000000000..2745a59d8d2 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.core.ts @@ -0,0 +1,76 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminListOrganizationMembers } from "../funcs/adminListOrganizationMembers.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminListOrganizationMembersResult } from "../models/components/adminlistorganizationmembersresult.js"; +import { AdminListOrganizationMembersRequest } from "../models/operations/adminlistorganizationmembers.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminListOrganizationMembersQueryData = + AdminListOrganizationMembersResult; + +export function prefetchAdminListOrganizationMembers( + queryClient: QueryClient, + client$: GramCore, + request: AdminListOrganizationMembersRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminListOrganizationMembersQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminListOrganizationMembersQuery( + client$: GramCore, + request: AdminListOrganizationMembersRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizationMembers({ + organizationId: request.organizationId, + }), + queryFn: async function adminListOrganizationMembersQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminListOrganizationMembers( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminListOrganizationMembers( + parameters: { organizationId: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "listOrganizationMembers", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.ts new file mode 100644 index 00000000000..6a0ca011306 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationMembers.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminListOrganizationMembersRequest } from "../models/operations/adminlistorganizationmembers.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminListOrganizationMembersQueryData, + buildAdminListOrganizationMembersQuery, + prefetchAdminListOrganizationMembers, + queryKeyAdminListOrganizationMembers, +} from "./adminListOrganizationMembers.core.js"; +export { + type AdminListOrganizationMembersQueryData, + buildAdminListOrganizationMembersQuery, + prefetchAdminListOrganizationMembers, + queryKeyAdminListOrganizationMembers, +}; + +export type AdminListOrganizationMembersQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * listOrganizationMembers admin + * + * @remarks + * Lists members of an organization (admin view, no auth scoping). + */ +export function useAdminListOrganizationMembers( + request: AdminListOrganizationMembersRequest, + options?: QueryHookOptions< + AdminListOrganizationMembersQueryData, + AdminListOrganizationMembersQueryError + >, +): UseQueryResult< + AdminListOrganizationMembersQueryData, + AdminListOrganizationMembersQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminListOrganizationMembersQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizationMembers admin + * + * @remarks + * Lists members of an organization (admin view, no auth scoping). + */ +export function useAdminListOrganizationMembersSuspense( + request: AdminListOrganizationMembersRequest, + options?: SuspenseQueryHookOptions< + AdminListOrganizationMembersQueryData, + AdminListOrganizationMembersQueryError + >, +): UseSuspenseQueryResult< + AdminListOrganizationMembersQueryData, + AdminListOrganizationMembersQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminListOrganizationMembersQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminListOrganizationMembersData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminListOrganizationMembersQueryData, +): AdminListOrganizationMembersQueryData | undefined { + const key = queryKeyAdminListOrganizationMembers(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminListOrganizationMembers( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "listOrganizationMembers", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminListOrganizationMembers( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "listOrganizationMembers"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.core.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.core.ts new file mode 100644 index 00000000000..8a4040437e8 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.core.ts @@ -0,0 +1,81 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminListOrganizationProjects } from "../funcs/adminListOrganizationProjects.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminListOrganizationProjectsResult } from "../models/components/adminlistorganizationprojectsresult.js"; +import { AdminListOrganizationProjectsRequest } from "../models/operations/adminlistorganizationprojects.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminListOrganizationProjectsQueryData = + AdminListOrganizationProjectsResult; + +export function prefetchAdminListOrganizationProjects( + queryClient: QueryClient, + client$: GramCore, + request: AdminListOrganizationProjectsRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminListOrganizationProjectsQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminListOrganizationProjectsQuery( + client$: GramCore, + request: AdminListOrganizationProjectsRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizationProjects({ + organizationId: request.organizationId, + }), + queryFn: async function adminListOrganizationProjectsQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminListOrganizationProjects( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminListOrganizationProjects( + parameters: { organizationId: string }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "listOrganizationProjects", + parameters, + ]; +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.ts b/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.ts new file mode 100644 index 00000000000..0aa75f98f7f --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizationProjects.ts @@ -0,0 +1,143 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminListOrganizationProjectsRequest } from "../models/operations/adminlistorganizationprojects.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminListOrganizationProjectsQueryData, + buildAdminListOrganizationProjectsQuery, + prefetchAdminListOrganizationProjects, + queryKeyAdminListOrganizationProjects, +} from "./adminListOrganizationProjects.core.js"; +export { + type AdminListOrganizationProjectsQueryData, + buildAdminListOrganizationProjectsQuery, + prefetchAdminListOrganizationProjects, + queryKeyAdminListOrganizationProjects, +}; + +export type AdminListOrganizationProjectsQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * listOrganizationProjects admin + * + * @remarks + * Lists projects belonging to an organization (admin view, no auth scoping). + */ +export function useAdminListOrganizationProjects( + request: AdminListOrganizationProjectsRequest, + options?: QueryHookOptions< + AdminListOrganizationProjectsQueryData, + AdminListOrganizationProjectsQueryError + >, +): UseQueryResult< + AdminListOrganizationProjectsQueryData, + AdminListOrganizationProjectsQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminListOrganizationProjectsQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizationProjects admin + * + * @remarks + * Lists projects belonging to an organization (admin view, no auth scoping). + */ +export function useAdminListOrganizationProjectsSuspense( + request: AdminListOrganizationProjectsRequest, + options?: SuspenseQueryHookOptions< + AdminListOrganizationProjectsQueryData, + AdminListOrganizationProjectsQueryError + >, +): UseSuspenseQueryResult< + AdminListOrganizationProjectsQueryData, + AdminListOrganizationProjectsQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminListOrganizationProjectsQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminListOrganizationProjectsData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminListOrganizationProjectsQueryData, +): AdminListOrganizationProjectsQueryData | undefined { + const key = queryKeyAdminListOrganizationProjects(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminListOrganizationProjects( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "listOrganizationProjects", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminListOrganizationProjects( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "listOrganizationProjects"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizations.core.ts b/client/admin/src/sdk/src/react-query/adminListOrganizations.core.ts new file mode 100644 index 00000000000..48de75f5b41 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizations.core.ts @@ -0,0 +1,207 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminListOrganizations } from "../funcs/adminListOrganizations.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { + AdminListOrganizationsRequest, + AdminListOrganizationsResponse, +} from "../models/operations/adminlistorganizations.js"; +import { unwrapAsync } from "../types/fp.js"; +import { PageIterator, unwrapResultIterator } from "../types/operations.js"; +import { pageIteratorToJSON } from "./_types.js"; +export type AdminListOrganizationsQueryData = AdminListOrganizationsResponse; + +export type AdminListOrganizationsInfiniteQueryData = PageIterator< + AdminListOrganizationsResponse, + { cursor: string } +>; + +export type AdminListOrganizationsPageParams = PageIterator< + AdminListOrganizationsResponse, + { cursor: string } +>["~next"]; + +export function prefetchAdminListOrganizations( + queryClient: QueryClient, + client$: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminListOrganizationsQuery( + client$, + request, + options, + ), + }); +} + +export function prefetchAdminListOrganizationsInfinite( + queryClient: QueryClient, + client$: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): Promise { + return queryClient.prefetchInfiniteQuery({ + ...buildAdminListOrganizationsInfiniteQuery( + client$, + request, + options, + ), + initialPageParam: undefined as AdminListOrganizationsPageParams, + getNextPageParam: (previousPage: AdminListOrganizationsInfiniteQueryData) => + previousPage["~next"], + }); +} + +export function buildAdminListOrganizationsQuery( + client$: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizations({ + q: request?.q, + accountType: request?.accountType, + accountTypes: request?.accountTypes, + trialStates: request?.trialStates, + disabledStates: request?.disabledStates, + includeDisabled: request?.includeDisabled, + cursor: request?.cursor, + limit: request?.limit, + sort: request?.sort, + direction: request?.direction, + page: request?.page, + }), + queryFn: async function adminListOrganizationsQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminListOrganizations( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function buildAdminListOrganizationsInfiniteQuery( + client$: GramCore, + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminListOrganizationsInfinite({ + q: request?.q, + accountType: request?.accountType, + accountTypes: request?.accountTypes, + trialStates: request?.trialStates, + disabledStates: request?.disabledStates, + includeDisabled: request?.includeDisabled, + cursor: request?.cursor, + limit: request?.limit, + sort: request?.sort, + direction: request?.direction, + page: request?.page, + }), + queryFn: async function adminListOrganizationsQuery( + ctx, + ): Promise { + const sig = combineSignals(ctx.signal, options?.fetchOptions?.signal); + const mergedOptions = { + ...options, + fetchOptions: { ...options?.fetchOptions, signal: sig }, + }; + + if (!ctx.pageParam) { + const pageResult = await unwrapResultIterator(adminListOrganizations( + client$, + request, + mergedOptions, + )); + return pageIteratorToJSON(pageResult); + } + const pageResult = await unwrapResultIterator(adminListOrganizations( + client$, + { + ...request!, + cursor: ctx.pageParam.cursor, + }, + mergedOptions, + )); + return pageIteratorToJSON(pageResult); + }, + }; +} + +export function queryKeyAdminListOrganizations( + parameters: { + q?: string | undefined; + accountType?: string | undefined; + accountTypes?: Array | undefined; + trialStates?: Array | undefined; + disabledStates?: Array | undefined; + includeDisabled?: boolean | undefined; + cursor?: string | undefined; + limit?: number | undefined; + sort?: string | undefined; + direction?: string | undefined; + page?: number | undefined; + }, +): QueryKey { + return ["@gram/admin-client", "admin", "listOrganizations", parameters]; +} + +export function queryKeyAdminListOrganizationsInfinite( + parameters: { + q?: string | undefined; + accountType?: string | undefined; + accountTypes?: Array | undefined; + trialStates?: Array | undefined; + disabledStates?: Array | undefined; + includeDisabled?: boolean | undefined; + cursor?: string | undefined; + limit?: number | undefined; + sort?: string | undefined; + direction?: string | undefined; + page?: number | undefined; + }, +): QueryKey { + return [ + "@gram/admin-client", + "admin", + "listOrganizations", + "infinite", + parameters, + ]; +} diff --git a/client/admin/src/sdk/src/react-query/adminListOrganizations.ts b/client/admin/src/sdk/src/react-query/adminListOrganizations.ts new file mode 100644 index 00000000000..018659d7316 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminListOrganizations.ts @@ -0,0 +1,271 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InfiniteData, + InvalidateQueryFilters, + QueryClient, + QueryKey, + useInfiniteQuery, + UseInfiniteQueryResult, + useQuery, + UseQueryResult, + useSuspenseInfiniteQuery, + UseSuspenseInfiniteQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminListOrganizationsRequest } from "../models/operations/adminlistorganizations.js"; +import { useGramContext } from "./_context.js"; +import { + InfiniteQueryHookOptions, + QueryHookOptions, + SuspenseInfiniteQueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsPageParams, + AdminListOrganizationsQueryData, + buildAdminListOrganizationsInfiniteQuery, + buildAdminListOrganizationsQuery, + prefetchAdminListOrganizations, + prefetchAdminListOrganizationsInfinite, + queryKeyAdminListOrganizations, + queryKeyAdminListOrganizationsInfinite, +} from "./adminListOrganizations.core.js"; +export { + type AdminListOrganizationsInfiniteQueryData, + type AdminListOrganizationsPageParams, + type AdminListOrganizationsQueryData, + buildAdminListOrganizationsInfiniteQuery, + buildAdminListOrganizationsQuery, + prefetchAdminListOrganizations, + prefetchAdminListOrganizationsInfinite, + queryKeyAdminListOrganizations, + queryKeyAdminListOrganizationsInfinite, +}; + +export type AdminListOrganizationsQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ +export function useAdminListOrganizations( + request?: AdminListOrganizationsRequest | undefined, + options?: QueryHookOptions< + AdminListOrganizationsQueryData, + AdminListOrganizationsQueryError + >, +): UseQueryResult< + AdminListOrganizationsQueryData, + AdminListOrganizationsQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminListOrganizationsQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ +export function useAdminListOrganizationsSuspense( + request?: AdminListOrganizationsRequest | undefined, + options?: SuspenseQueryHookOptions< + AdminListOrganizationsQueryData, + AdminListOrganizationsQueryError + >, +): UseSuspenseQueryResult< + AdminListOrganizationsQueryData, + AdminListOrganizationsQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminListOrganizationsQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ +export function useAdminListOrganizationsInfinite( + request?: AdminListOrganizationsRequest | undefined, + options?: InfiniteQueryHookOptions< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsQueryError + >, +): UseInfiniteQueryResult< + InfiniteData< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsPageParams + >, + AdminListOrganizationsQueryError +> { + const client = useGramContext(); + return useInfiniteQuery< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsQueryError, + InfiniteData< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsPageParams + >, + QueryKey, + AdminListOrganizationsPageParams + >({ + ...buildAdminListOrganizationsInfiniteQuery( + client, + request, + options, + ), + initialPageParam: options?.initialPageParam, + getNextPageParam: (previousPage) => previousPage["~next"], + ...options, + }); +} + +/** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ +export function useAdminListOrganizationsInfiniteSuspense( + request?: AdminListOrganizationsRequest | undefined, + options?: SuspenseInfiniteQueryHookOptions< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsQueryError + >, +): UseSuspenseInfiniteQueryResult< + InfiniteData< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsPageParams + >, + AdminListOrganizationsQueryError +> { + const client = useGramContext(); + return useSuspenseInfiniteQuery< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsQueryError, + InfiniteData< + AdminListOrganizationsInfiniteQueryData, + AdminListOrganizationsPageParams + >, + QueryKey, + AdminListOrganizationsPageParams + >({ + ...buildAdminListOrganizationsInfiniteQuery( + client, + request, + options, + ), + initialPageParam: options?.initialPageParam, + getNextPageParam: (previousPage) => previousPage["~next"], + ...options, + }); +} + +export function setAdminListOrganizationsData( + client: QueryClient, + queryKeyBase: [ + parameters: { + q?: string | undefined; + accountType?: string | undefined; + accountTypes?: Array | undefined; + trialStates?: Array | undefined; + disabledStates?: Array | undefined; + includeDisabled?: boolean | undefined; + cursor?: string | undefined; + limit?: number | undefined; + sort?: string | undefined; + direction?: string | undefined; + page?: number | undefined; + }, + ], + data: AdminListOrganizationsQueryData, +): AdminListOrganizationsQueryData | undefined { + const key = queryKeyAdminListOrganizations(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminListOrganizations( + client: QueryClient, + queryKeyBase: TupleToPrefixes< + [parameters: { + q?: string | undefined; + accountType?: string | undefined; + accountTypes?: Array | undefined; + trialStates?: Array | undefined; + disabledStates?: Array | undefined; + includeDisabled?: boolean | undefined; + cursor?: string | undefined; + limit?: number | undefined; + sort?: string | undefined; + direction?: string | undefined; + page?: number | undefined; + }] + >, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "listOrganizations", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminListOrganizations( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "listOrganizations"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminLogout.ts b/client/admin/src/sdk/src/react-query/adminLogout.ts new file mode 100644 index 00000000000..ba6551472d4 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminLogout.ts @@ -0,0 +1,103 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminLogout } from "../funcs/adminLogout.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminLogoutMutationVariables = { + options?: RequestOptions; +}; + +export type AdminLogoutMutationData = void; + +export type AdminLogoutMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * logout admin + */ +export function useAdminLogoutMutation( + options?: MutationHookOptions< + AdminLogoutMutationData, + AdminLogoutMutationError, + AdminLogoutMutationVariables + >, +): UseMutationResult< + AdminLogoutMutationData, + AdminLogoutMutationError, + AdminLogoutMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminLogoutMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminLogout(): MutationKey { + return ["@gram/admin-client", "admin", "logout"]; +} + +export function buildAdminLogoutMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminLogoutMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminLogout(), + mutationFn: function adminLogoutMutationFn({ + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminLogout( + client$, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminMarkEnterpriseTrialConverted.ts b/client/admin/src/sdk/src/react-query/adminMarkEnterpriseTrialConverted.ts new file mode 100644 index 00000000000..11585aef01d --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminMarkEnterpriseTrialConverted.ts @@ -0,0 +1,112 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminMarkEnterpriseTrialConverted } from "../funcs/adminMarkEnterpriseTrialConverted.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { MarkEnterpriseTrialConvertedRequestBody } from "../models/components/markenterprisetrialconvertedrequestbody.js"; +import { MarkEnterpriseTrialConvertedResult } from "../models/components/markenterprisetrialconvertedresult.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminMarkEnterpriseTrialConvertedMutationVariables = { + request: MarkEnterpriseTrialConvertedRequestBody; + options?: RequestOptions; +}; + +export type AdminMarkEnterpriseTrialConvertedMutationData = + MarkEnterpriseTrialConvertedResult; + +export type AdminMarkEnterpriseTrialConvertedMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * markEnterpriseTrialConverted admin + * + * @remarks + * Records that an organization's enterprise trial converted to a signed contract. + */ +export function useAdminMarkEnterpriseTrialConvertedMutation( + options?: MutationHookOptions< + AdminMarkEnterpriseTrialConvertedMutationData, + AdminMarkEnterpriseTrialConvertedMutationError, + AdminMarkEnterpriseTrialConvertedMutationVariables + >, +): UseMutationResult< + AdminMarkEnterpriseTrialConvertedMutationData, + AdminMarkEnterpriseTrialConvertedMutationError, + AdminMarkEnterpriseTrialConvertedMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminMarkEnterpriseTrialConvertedMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminMarkEnterpriseTrialConverted(): MutationKey { + return ["@gram/admin-client", "admin", "markEnterpriseTrialConverted"]; +} + +export function buildAdminMarkEnterpriseTrialConvertedMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminMarkEnterpriseTrialConvertedMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminMarkEnterpriseTrialConverted(), + mutationFn: function adminMarkEnterpriseTrialConvertedMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminMarkEnterpriseTrialConverted( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.core.ts b/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.core.ts new file mode 100644 index 00000000000..1b4405d13d0 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.core.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + QueryClient, + QueryFunctionContext, + QueryKey, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminGetOrganizationFeatures } from "../funcs/adminGetOrganizationFeatures.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { ProductFeatures } from "../models/components/productfeatures.js"; +import { AdminGetOrganizationFeaturesRequest } from "../models/operations/admingetorganizationfeatures.js"; +import { unwrapAsync } from "../types/fp.js"; +export type AdminOrganizationFeaturesQueryData = ProductFeatures; + +export function prefetchAdminOrganizationFeatures( + queryClient: QueryClient, + client$: GramCore, + request: AdminGetOrganizationFeaturesRequest, + options?: RequestOptions, +): Promise { + return queryClient.prefetchQuery({ + ...buildAdminOrganizationFeaturesQuery( + client$, + request, + options, + ), + }); +} + +export function buildAdminOrganizationFeaturesQuery( + client$: GramCore, + request: AdminGetOrganizationFeaturesRequest, + options?: RequestOptions, +): { + queryKey: QueryKey; + queryFn: ( + context: QueryFunctionContext, + ) => Promise; +} { + return { + queryKey: queryKeyAdminOrganizationFeatures({ + organizationId: request.organizationId, + }), + queryFn: async function adminOrganizationFeaturesQueryFn( + ctx, + ): Promise { + const sig = combineSignals( + ctx.signal, + options?.signal, + options?.fetchOptions?.signal, + ); + const mergedOptions = { + ...options?.fetchOptions, + ...options, + signal: sig, + }; + + return unwrapAsync(adminGetOrganizationFeatures( + client$, + request, + mergedOptions, + )); + }, + }; +} + +export function queryKeyAdminOrganizationFeatures( + parameters: { organizationId: string }, +): QueryKey { + return ["@gram/admin-client", "admin", "getOrganizationFeatures", parameters]; +} diff --git a/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.ts b/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.ts new file mode 100644 index 00000000000..e75d0201ca4 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminOrganizationFeatures.ts @@ -0,0 +1,137 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + InvalidateQueryFilters, + QueryClient, + useQuery, + UseQueryResult, + useSuspenseQuery, + UseSuspenseQueryResult, +} from "@tanstack/react-query"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { AdminGetOrganizationFeaturesRequest } from "../models/operations/admingetorganizationfeatures.js"; +import { useGramContext } from "./_context.js"; +import { + QueryHookOptions, + SuspenseQueryHookOptions, + TupleToPrefixes, +} from "./_types.js"; +import { + AdminOrganizationFeaturesQueryData, + buildAdminOrganizationFeaturesQuery, + prefetchAdminOrganizationFeatures, + queryKeyAdminOrganizationFeatures, +} from "./adminOrganizationFeatures.core.js"; +export { + type AdminOrganizationFeaturesQueryData, + buildAdminOrganizationFeaturesQuery, + prefetchAdminOrganizationFeatures, + queryKeyAdminOrganizationFeatures, +}; + +export type AdminOrganizationFeaturesQueryError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * getOrganizationFeatures admin + */ +export function useAdminOrganizationFeatures( + request: AdminGetOrganizationFeaturesRequest, + options?: QueryHookOptions< + AdminOrganizationFeaturesQueryData, + AdminOrganizationFeaturesQueryError + >, +): UseQueryResult< + AdminOrganizationFeaturesQueryData, + AdminOrganizationFeaturesQueryError +> { + const client = useGramContext(); + return useQuery({ + ...buildAdminOrganizationFeaturesQuery( + client, + request, + options, + ), + ...options, + }); +} + +/** + * getOrganizationFeatures admin + */ +export function useAdminOrganizationFeaturesSuspense( + request: AdminGetOrganizationFeaturesRequest, + options?: SuspenseQueryHookOptions< + AdminOrganizationFeaturesQueryData, + AdminOrganizationFeaturesQueryError + >, +): UseSuspenseQueryResult< + AdminOrganizationFeaturesQueryData, + AdminOrganizationFeaturesQueryError +> { + const client = useGramContext(); + return useSuspenseQuery({ + ...buildAdminOrganizationFeaturesQuery( + client, + request, + options, + ), + ...options, + }); +} + +export function setAdminOrganizationFeaturesData( + client: QueryClient, + queryKeyBase: [parameters: { organizationId: string }], + data: AdminOrganizationFeaturesQueryData, +): AdminOrganizationFeaturesQueryData | undefined { + const key = queryKeyAdminOrganizationFeatures(...queryKeyBase); + + return client.setQueryData(key, data); +} + +export function invalidateAdminOrganizationFeatures( + client: QueryClient, + queryKeyBase: TupleToPrefixes<[parameters: { organizationId: string }]>, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: [ + "@gram/admin-client", + "admin", + "getOrganizationFeatures", + ...queryKeyBase, + ], + }); +} + +export function invalidateAllAdminOrganizationFeatures( + client: QueryClient, + filters?: Omit, +): Promise { + return client.invalidateQueries({ + ...filters, + queryKey: ["@gram/admin-client", "admin", "getOrganizationFeatures"], + }); +} diff --git a/client/admin/src/sdk/src/react-query/adminRearmTrial.ts b/client/admin/src/sdk/src/react-query/adminRearmTrial.ts new file mode 100644 index 00000000000..e6fc5cd3134 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminRearmTrial.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminRearmTrial } from "../funcs/adminRearmTrial.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { RearmTrialRequestBody } from "../models/components/rearmtrialrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminRearmTrialMutationVariables = { + request: RearmTrialRequestBody; + options?: RequestOptions; +}; + +export type AdminRearmTrialMutationData = AdminOrganization; + +export type AdminRearmTrialMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * rearmTrial admin + * + * @remarks + * Puts a demoted enterprise trial back on: restores the organization's account type and whitelist flag, revives its model provider keys, and gives the trial a fresh run of the given length counted from now. Only a demoted trial can be re-armed; one that has converted or is already running is rejected. + */ +export function useAdminRearmTrialMutation( + options?: MutationHookOptions< + AdminRearmTrialMutationData, + AdminRearmTrialMutationError, + AdminRearmTrialMutationVariables + >, +): UseMutationResult< + AdminRearmTrialMutationData, + AdminRearmTrialMutationError, + AdminRearmTrialMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminRearmTrialMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminRearmTrial(): MutationKey { + return ["@gram/admin-client", "admin", "rearmTrial"]; +} + +export function buildAdminRearmTrialMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminRearmTrialMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminRearmTrial(), + mutationFn: function adminRearmTrialMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminRearmTrial( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminResumeStripeSubscription.ts b/client/admin/src/sdk/src/react-query/adminResumeStripeSubscription.ts new file mode 100644 index 00000000000..3db2dbc34b1 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminResumeStripeSubscription.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminResumeStripeSubscription } from "../funcs/adminResumeStripeSubscription.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminStripeSubscription } from "../models/components/adminstripesubscription.js"; +import { ResumeStripeSubscriptionRequestBody } from "../models/components/resumestripesubscriptionrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminResumeStripeSubscriptionMutationVariables = { + request: ResumeStripeSubscriptionRequestBody; + options?: RequestOptions; +}; + +export type AdminResumeStripeSubscriptionMutationData = AdminStripeSubscription; + +export type AdminResumeStripeSubscriptionMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * resumeStripeSubscription admin + * + * @remarks + * Removes a scheduled period-end cancellation from an organization's PAYG subscription. + */ +export function useAdminResumeStripeSubscriptionMutation( + options?: MutationHookOptions< + AdminResumeStripeSubscriptionMutationData, + AdminResumeStripeSubscriptionMutationError, + AdminResumeStripeSubscriptionMutationVariables + >, +): UseMutationResult< + AdminResumeStripeSubscriptionMutationData, + AdminResumeStripeSubscriptionMutationError, + AdminResumeStripeSubscriptionMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminResumeStripeSubscriptionMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminResumeStripeSubscription(): MutationKey { + return ["@gram/admin-client", "admin", "resumeStripeSubscription"]; +} + +export function buildAdminResumeStripeSubscriptionMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminResumeStripeSubscriptionMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminResumeStripeSubscription(), + mutationFn: function adminResumeStripeSubscriptionMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminResumeStripeSubscription( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminSetInferenceKeyMonthlyLimit.ts b/client/admin/src/sdk/src/react-query/adminSetInferenceKeyMonthlyLimit.ts new file mode 100644 index 00000000000..eaa409c1617 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminSetInferenceKeyMonthlyLimit.ts @@ -0,0 +1,112 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminSetInferenceKeyMonthlyLimit } from "../funcs/adminSetInferenceKeyMonthlyLimit.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminInferenceKeyLimit } from "../models/components/admininferencekeylimit.js"; +import { SetInferenceKeyMonthlyLimitRequestBody } from "../models/components/setinferencekeymonthlylimitrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminSetInferenceKeyMonthlyLimitMutationVariables = { + request: SetInferenceKeyMonthlyLimitRequestBody; + options?: RequestOptions; +}; + +export type AdminSetInferenceKeyMonthlyLimitMutationData = + AdminInferenceKeyLimit; + +export type AdminSetInferenceKeyMonthlyLimitMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * setInferenceKeyMonthlyLimit admin + * + * @remarks + * Sets the monthly limit for one materialized platform-managed OpenRouter key. + */ +export function useAdminSetInferenceKeyMonthlyLimitMutation( + options?: MutationHookOptions< + AdminSetInferenceKeyMonthlyLimitMutationData, + AdminSetInferenceKeyMonthlyLimitMutationError, + AdminSetInferenceKeyMonthlyLimitMutationVariables + >, +): UseMutationResult< + AdminSetInferenceKeyMonthlyLimitMutationData, + AdminSetInferenceKeyMonthlyLimitMutationError, + AdminSetInferenceKeyMonthlyLimitMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminSetInferenceKeyMonthlyLimitMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminSetInferenceKeyMonthlyLimit(): MutationKey { + return ["@gram/admin-client", "admin", "setInferenceKeyMonthlyLimit"]; +} + +export function buildAdminSetInferenceKeyMonthlyLimitMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminSetInferenceKeyMonthlyLimitMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminSetInferenceKeyMonthlyLimit(), + mutationFn: function adminSetInferenceKeyMonthlyLimitMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminSetInferenceKeyMonthlyLimit( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminSetOrganizationChatAnalysisSettings.ts b/client/admin/src/sdk/src/react-query/adminSetOrganizationChatAnalysisSettings.ts new file mode 100644 index 00000000000..b5714993179 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminSetOrganizationChatAnalysisSettings.ts @@ -0,0 +1,109 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminSetOrganizationChatAnalysisSettings } from "../funcs/adminSetOrganizationChatAnalysisSettings.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminChatAnalysisSettings } from "../models/components/adminchatanalysissettings.js"; +import { SetOrganizationChatAnalysisSettingsRequestBody } from "../models/components/setorganizationchatanalysissettingsrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminSetOrganizationChatAnalysisSettingsMutationVariables = { + request: SetOrganizationChatAnalysisSettingsRequestBody; + options?: RequestOptions; +}; + +export type AdminSetOrganizationChatAnalysisSettingsMutationData = + AdminChatAnalysisSettings; + +export type AdminSetOrganizationChatAnalysisSettingsMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * setOrganizationChatAnalysisSettings admin + */ +export function useAdminSetOrganizationChatAnalysisSettingsMutation( + options?: MutationHookOptions< + AdminSetOrganizationChatAnalysisSettingsMutationData, + AdminSetOrganizationChatAnalysisSettingsMutationError, + AdminSetOrganizationChatAnalysisSettingsMutationVariables + >, +): UseMutationResult< + AdminSetOrganizationChatAnalysisSettingsMutationData, + AdminSetOrganizationChatAnalysisSettingsMutationError, + AdminSetOrganizationChatAnalysisSettingsMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminSetOrganizationChatAnalysisSettingsMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminSetOrganizationChatAnalysisSettings(): MutationKey { + return ["@gram/admin-client", "admin", "setOrganizationChatAnalysisSettings"]; +} + +export function buildAdminSetOrganizationChatAnalysisSettingsMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminSetOrganizationChatAnalysisSettingsMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminSetOrganizationChatAnalysisSettings(), + mutationFn: function adminSetOrganizationChatAnalysisSettingsMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminSetOrganizationChatAnalysisSettings( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminTriggerOrganizationChatAnalysis.ts b/client/admin/src/sdk/src/react-query/adminTriggerOrganizationChatAnalysis.ts new file mode 100644 index 00000000000..cef4f493fc2 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminTriggerOrganizationChatAnalysis.ts @@ -0,0 +1,109 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminTriggerOrganizationChatAnalysis } from "../funcs/adminTriggerOrganizationChatAnalysis.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminChatAnalysisTriggerResult } from "../models/components/adminchatanalysistriggerresult.js"; +import { TriggerOrganizationChatAnalysisRequestBody } from "../models/components/triggerorganizationchatanalysisrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminTriggerOrganizationChatAnalysisMutationVariables = { + request: TriggerOrganizationChatAnalysisRequestBody; + options?: RequestOptions; +}; + +export type AdminTriggerOrganizationChatAnalysisMutationData = + AdminChatAnalysisTriggerResult; + +export type AdminTriggerOrganizationChatAnalysisMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * triggerOrganizationChatAnalysis admin + */ +export function useAdminTriggerOrganizationChatAnalysisMutation( + options?: MutationHookOptions< + AdminTriggerOrganizationChatAnalysisMutationData, + AdminTriggerOrganizationChatAnalysisMutationError, + AdminTriggerOrganizationChatAnalysisMutationVariables + >, +): UseMutationResult< + AdminTriggerOrganizationChatAnalysisMutationData, + AdminTriggerOrganizationChatAnalysisMutationError, + AdminTriggerOrganizationChatAnalysisMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminTriggerOrganizationChatAnalysisMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminTriggerOrganizationChatAnalysis(): MutationKey { + return ["@gram/admin-client", "admin", "triggerOrganizationChatAnalysis"]; +} + +export function buildAdminTriggerOrganizationChatAnalysisMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminTriggerOrganizationChatAnalysisMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminTriggerOrganizationChatAnalysis(), + mutationFn: function adminTriggerOrganizationChatAnalysisMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminTriggerOrganizationChatAnalysis( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/adminUpdateOrganization.ts b/client/admin/src/sdk/src/react-query/adminUpdateOrganization.ts new file mode 100644 index 00000000000..5a8fb81eb4a --- /dev/null +++ b/client/admin/src/sdk/src/react-query/adminUpdateOrganization.ts @@ -0,0 +1,111 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminUpdateOrganization } from "../funcs/adminUpdateOrganization.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { UpdateOrganizationRequestBody } from "../models/components/updateorganizationrequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type AdminUpdateOrganizationMutationVariables = { + request: UpdateOrganizationRequestBody; + options?: RequestOptions; +}; + +export type AdminUpdateOrganizationMutationData = AdminOrganization; + +export type AdminUpdateOrganizationMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * updateOrganization admin + * + * @remarks + * Updates admin-managed fields on an organization. At least one of account_type or whitelisted must be supplied. + */ +export function useAdminUpdateOrganizationMutation( + options?: MutationHookOptions< + AdminUpdateOrganizationMutationData, + AdminUpdateOrganizationMutationError, + AdminUpdateOrganizationMutationVariables + >, +): UseMutationResult< + AdminUpdateOrganizationMutationData, + AdminUpdateOrganizationMutationError, + AdminUpdateOrganizationMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildAdminUpdateOrganizationMutation(client, options), + ...options, + }); +} + +export function mutationKeyAdminUpdateOrganization(): MutationKey { + return ["@gram/admin-client", "admin", "updateOrganization"]; +} + +export function buildAdminUpdateOrganizationMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: AdminUpdateOrganizationMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeyAdminUpdateOrganization(), + mutationFn: function adminUpdateOrganizationMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminUpdateOrganization( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/react-query/index.ts b/client/admin/src/sdk/src/react-query/index.ts new file mode 100644 index 00000000000..76ff9b6fc8d --- /dev/null +++ b/client/admin/src/sdk/src/react-query/index.ts @@ -0,0 +1,6 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export { GramProvider, useGramContext } from "./_context.js"; +export * from "./_types.js"; diff --git a/client/admin/src/sdk/src/react-query/setAdminOrganizationFeature.ts b/client/admin/src/sdk/src/react-query/setAdminOrganizationFeature.ts new file mode 100644 index 00000000000..4b085227588 --- /dev/null +++ b/client/admin/src/sdk/src/react-query/setAdminOrganizationFeature.ts @@ -0,0 +1,108 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + MutationKey, + useMutation, + UseMutationResult, +} from "@tanstack/react-query"; +import { GramCore } from "../core.js"; +import { adminSetOrganizationFeature } from "../funcs/adminSetOrganizationFeature.js"; +import { combineSignals } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { ProductFeatures } from "../models/components/productfeatures.js"; +import { SetOrganizationFeatureRequestBody } from "../models/components/setorganizationfeaturerequestbody.js"; +import { GramError } from "../models/errors/gramerror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ServiceError } from "../models/errors/serviceerror.js"; +import { unwrapAsync } from "../types/fp.js"; +import { useGramContext } from "./_context.js"; +import { MutationHookOptions } from "./_types.js"; + +export type SetAdminOrganizationFeatureMutationVariables = { + request: SetOrganizationFeatureRequestBody; + options?: RequestOptions; +}; + +export type SetAdminOrganizationFeatureMutationData = ProductFeatures; + +export type SetAdminOrganizationFeatureMutationError = + | ServiceError + | GramError + | ResponseValidationError + | ConnectionError + | RequestAbortedError + | RequestTimeoutError + | InvalidRequestError + | UnexpectedClientError + | SDKValidationError; + +/** + * setOrganizationFeature admin + */ +export function useSetAdminOrganizationFeatureMutation( + options?: MutationHookOptions< + SetAdminOrganizationFeatureMutationData, + SetAdminOrganizationFeatureMutationError, + SetAdminOrganizationFeatureMutationVariables + >, +): UseMutationResult< + SetAdminOrganizationFeatureMutationData, + SetAdminOrganizationFeatureMutationError, + SetAdminOrganizationFeatureMutationVariables +> { + const client = useGramContext(); + return useMutation({ + ...buildSetAdminOrganizationFeatureMutation(client, options), + ...options, + }); +} + +export function mutationKeySetAdminOrganizationFeature(): MutationKey { + return ["@gram/admin-client", "admin", "setOrganizationFeature"]; +} + +export function buildSetAdminOrganizationFeatureMutation( + client$: GramCore, + hookOptions?: RequestOptions, +): { + mutationKey: MutationKey; + mutationFn: ( + variables: SetAdminOrganizationFeatureMutationVariables, + ) => Promise; +} { + return { + mutationKey: mutationKeySetAdminOrganizationFeature(), + mutationFn: function setAdminOrganizationFeatureMutationFn({ + request, + options, + }): Promise { + const mergedOptions = { + ...hookOptions, + ...options, + fetchOptions: { + ...hookOptions?.fetchOptions, + ...options?.fetchOptions, + signal: combineSignals( + hookOptions?.fetchOptions?.signal, + options?.fetchOptions?.signal, + ), + }, + }; + return unwrapAsync(adminSetOrganizationFeature( + client$, + request, + mergedOptions, + )); + }, + }; +} diff --git a/client/admin/src/sdk/src/sdk/admin.ts b/client/admin/src/sdk/src/sdk/admin.ts new file mode 100644 index 00000000000..1065f18714f --- /dev/null +++ b/client/admin/src/sdk/src/sdk/admin.ts @@ -0,0 +1,554 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { adminBulkUpdateAccountType } from "../funcs/adminBulkUpdateAccountType.js"; +import { adminCancelStripeSubscription } from "../funcs/adminCancelStripeSubscription.js"; +import { adminCreateOrganization } from "../funcs/adminCreateOrganization.js"; +import { adminDisableOrganization } from "../funcs/adminDisableOrganization.js"; +import { adminEnableOrganization } from "../funcs/adminEnableOrganization.js"; +import { adminExtendTrial } from "../funcs/adminExtendTrial.js"; +import { adminGetInferenceKeys } from "../funcs/adminGetInferenceKeys.js"; +import { adminGetInferenceSpendHistory } from "../funcs/adminGetInferenceSpendHistory.js"; +import { adminGetOrganization } from "../funcs/adminGetOrganization.js"; +import { adminGetOrganizationChatAnalysisSettings } from "../funcs/adminGetOrganizationChatAnalysisSettings.js"; +import { adminGetOrganizationFeatures } from "../funcs/adminGetOrganizationFeatures.js"; +import { adminGetOrganizationStats } from "../funcs/adminGetOrganizationStats.js"; +import { adminGetPaygBillingSummary } from "../funcs/adminGetPaygBillingSummary.js"; +import { adminGetProject } from "../funcs/adminGetProject.js"; +import { adminGetSession } from "../funcs/adminGetSession.js"; +import { adminGetStripeSubscription } from "../funcs/adminGetStripeSubscription.js"; +import { adminListOrganizationActivity } from "../funcs/adminListOrganizationActivity.js"; +import { adminListOrganizationMembers } from "../funcs/adminListOrganizationMembers.js"; +import { adminListOrganizationProjects } from "../funcs/adminListOrganizationProjects.js"; +import { adminListOrganizations } from "../funcs/adminListOrganizations.js"; +import { adminLogout } from "../funcs/adminLogout.js"; +import { adminMarkEnterpriseTrialConverted } from "../funcs/adminMarkEnterpriseTrialConverted.js"; +import { adminRearmTrial } from "../funcs/adminRearmTrial.js"; +import { adminResumeStripeSubscription } from "../funcs/adminResumeStripeSubscription.js"; +import { adminSetInferenceKeyMonthlyLimit } from "../funcs/adminSetInferenceKeyMonthlyLimit.js"; +import { adminSetOrganizationChatAnalysisSettings } from "../funcs/adminSetOrganizationChatAnalysisSettings.js"; +import { adminSetOrganizationFeature } from "../funcs/adminSetOrganizationFeature.js"; +import { adminTriggerOrganizationChatAnalysis } from "../funcs/adminTriggerOrganizationChatAnalysis.js"; +import { adminUpdateOrganization } from "../funcs/adminUpdateOrganization.js"; +import { ClientSDK, RequestOptions } from "../lib/sdks.js"; +import { AdminBulkUpdateAccountTypeResult } from "../models/components/adminbulkupdateaccounttyperesult.js"; +import { AdminChatAnalysisSettings } from "../models/components/adminchatanalysissettings.js"; +import { AdminChatAnalysisTriggerResult } from "../models/components/adminchatanalysistriggerresult.js"; +import { AdminInferenceKey } from "../models/components/admininferencekey.js"; +import { AdminInferenceKeyLimit } from "../models/components/admininferencekeylimit.js"; +import { AdminInferenceSpendMonth } from "../models/components/admininferencespendmonth.js"; +import { AdminListOrganizationMembersResult } from "../models/components/adminlistorganizationmembersresult.js"; +import { AdminListOrganizationProjectsResult } from "../models/components/adminlistorganizationprojectsresult.js"; +import { AdminOrganization } from "../models/components/adminorganization.js"; +import { AdminOrganizationStats } from "../models/components/adminorganizationstats.js"; +import { AdminPaygBillingSummary } from "../models/components/adminpaygbillingsummary.js"; +import { AdminProjectDetail } from "../models/components/adminprojectdetail.js"; +import { AdminSession } from "../models/components/adminsession.js"; +import { AdminStripeSubscription } from "../models/components/adminstripesubscription.js"; +import { BulkUpdateAccountTypeRequestBody } from "../models/components/bulkupdateaccounttyperequestbody.js"; +import { CancelStripeSubscriptionRequestBody } from "../models/components/cancelstripesubscriptionrequestbody.js"; +import { CreateOrganizationRequestBody } from "../models/components/createorganizationrequestbody.js"; +import { DisableOrganizationRequestBody } from "../models/components/disableorganizationrequestbody.js"; +import { EnableOrganizationRequestBody } from "../models/components/enableorganizationrequestbody.js"; +import { ExtendTrialRequestBody } from "../models/components/extendtrialrequestbody.js"; +import { MarkEnterpriseTrialConvertedRequestBody } from "../models/components/markenterprisetrialconvertedrequestbody.js"; +import { MarkEnterpriseTrialConvertedResult } from "../models/components/markenterprisetrialconvertedresult.js"; +import { ProductFeatures } from "../models/components/productfeatures.js"; +import { RearmTrialRequestBody } from "../models/components/rearmtrialrequestbody.js"; +import { ResumeStripeSubscriptionRequestBody } from "../models/components/resumestripesubscriptionrequestbody.js"; +import { SetInferenceKeyMonthlyLimitRequestBody } from "../models/components/setinferencekeymonthlylimitrequestbody.js"; +import { SetOrganizationChatAnalysisSettingsRequestBody } from "../models/components/setorganizationchatanalysissettingsrequestbody.js"; +import { SetOrganizationFeatureRequestBody } from "../models/components/setorganizationfeaturerequestbody.js"; +import { TriggerOrganizationChatAnalysisRequestBody } from "../models/components/triggerorganizationchatanalysisrequestbody.js"; +import { UpdateOrganizationRequestBody } from "../models/components/updateorganizationrequestbody.js"; +import { AdminGetInferenceKeysRequest } from "../models/operations/admingetinferencekeys.js"; +import { AdminGetInferenceSpendHistoryRequest } from "../models/operations/admingetinferencespendhistory.js"; +import { AdminGetOrganizationRequest } from "../models/operations/admingetorganization.js"; +import { AdminGetOrganizationChatAnalysisSettingsRequest } from "../models/operations/admingetorganizationchatanalysissettings.js"; +import { AdminGetOrganizationFeaturesRequest } from "../models/operations/admingetorganizationfeatures.js"; +import { AdminGetPaygBillingSummaryRequest } from "../models/operations/admingetpaygbillingsummary.js"; +import { AdminGetProjectRequest } from "../models/operations/admingetproject.js"; +import { AdminGetStripeSubscriptionRequest } from "../models/operations/admingetstripesubscription.js"; +import { + AdminListOrganizationActivityRequest, + AdminListOrganizationActivityResponse, +} from "../models/operations/adminlistorganizationactivity.js"; +import { AdminListOrganizationMembersRequest } from "../models/operations/adminlistorganizationmembers.js"; +import { AdminListOrganizationProjectsRequest } from "../models/operations/adminlistorganizationprojects.js"; +import { + AdminListOrganizationsRequest, + AdminListOrganizationsResponse, +} from "../models/operations/adminlistorganizations.js"; +import { unwrapAsync } from "../types/fp.js"; +import { PageIterator, unwrapResultIterator } from "../types/operations.js"; + +export class Admin extends ClientSDK { + /** + * logout admin + */ + async logout( + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminLogout( + this, + options, + )); + } + + /** + * listOrganizationActivity admin + * + * @remarks + * Lists activity belonging to an organization for admin operators. + */ + async listOrganizationActivity( + request: AdminListOrganizationActivityRequest, + options?: RequestOptions, + ): Promise< + PageIterator + > { + return unwrapResultIterator(adminListOrganizationActivity( + this, + request, + options, + )); + } + + /** + * cancelStripeSubscription admin + * + * @remarks + * Schedules an organization's PAYG subscription to cancel at period end. + */ + async cancelStripeSubscription( + request: CancelStripeSubscriptionRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminCancelStripeSubscription( + this, + request, + options, + )); + } + + /** + * getOrganizationChatAnalysisSettings admin + */ + async getOrganizationChatAnalysisSettings( + request: AdminGetOrganizationChatAnalysisSettingsRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetOrganizationChatAnalysisSettings( + this, + request, + options, + )); + } + + /** + * setOrganizationChatAnalysisSettings admin + */ + async setOrganizationChatAnalysisSettings( + request: SetOrganizationChatAnalysisSettingsRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminSetOrganizationChatAnalysisSettings( + this, + request, + options, + )); + } + + /** + * triggerOrganizationChatAnalysis admin + */ + async triggerOrganizationChatAnalysis( + request: TriggerOrganizationChatAnalysisRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminTriggerOrganizationChatAnalysis( + this, + request, + options, + )); + } + + /** + * createOrganization admin + * + * @remarks + * Creates an organization in WorkOS and in Gram, so an operator does not have to leave the admin app for the WorkOS dashboard. The organization starts with no members, is not whitelisted, and gets no trial. Idempotent against the WorkOS organization webhook: the Gram ID is derived from the WorkOS ID, so both writers converge on one row. + */ + async createOrganization( + request: CreateOrganizationRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminCreateOrganization( + this, + request, + options, + )); + } + + /** + * disableOrganization admin + * + * @remarks + * Disables an organization, recording the moment of the action in disabled_at. Idempotent: disabling an already-disabled organization keeps the original timestamp. + */ + async disableOrganization( + request: DisableOrganizationRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminDisableOrganization( + this, + request, + options, + )); + } + + /** + * enableOrganization admin + * + * @remarks + * Re-enables a disabled organization by clearing disabled_at. Idempotent: an organization that is already active is unaffected. + */ + async enableOrganization( + request: EnableOrganizationRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminEnableOrganization( + this, + request, + options, + )); + } + + /** + * getOrganizationFeatures admin + */ + async getOrganizationFeatures( + request: AdminGetOrganizationFeaturesRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetOrganizationFeatures( + this, + request, + options, + )); + } + + /** + * setOrganizationFeature admin + */ + async setOrganizationFeature( + request: SetOrganizationFeatureRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminSetOrganizationFeature( + this, + request, + options, + )); + } + + /** + * getOrganization admin + * + * @remarks + * Returns full admin details for a single organization by id or slug. + */ + async getOrganization( + request: AdminGetOrganizationRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetOrganization( + this, + request, + options, + )); + } + + /** + * getInferenceKeys admin + * + * @remarks + * Returns the configured state of every materialized platform-managed OpenRouter key for an organization. + */ + async getInferenceKeys( + request: AdminGetInferenceKeysRequest, + options?: RequestOptions, + ): Promise> { + return unwrapAsync(adminGetInferenceKeys( + this, + request, + options, + )); + } + + /** + * getInferenceSpendHistory admin + * + * @remarks + * Returns up to twelve complete UTC calendar months of recorded inference spend for an organization. + */ + async getInferenceSpendHistory( + request: AdminGetInferenceSpendHistoryRequest, + options?: RequestOptions, + ): Promise> { + return unwrapAsync(adminGetInferenceSpendHistory( + this, + request, + options, + )); + } + + /** + * listOrganizationMembers admin + * + * @remarks + * Lists members of an organization (admin view, no auth scoping). + */ + async listOrganizationMembers( + request: AdminListOrganizationMembersRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminListOrganizationMembers( + this, + request, + options, + )); + } + + /** + * getPaygBillingSummary admin + * + * @remarks + * Returns current PAYG usage and estimated cost for an organization. + */ + async getPaygBillingSummary( + request: AdminGetPaygBillingSummaryRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetPaygBillingSummary( + this, + request, + options, + )); + } + + /** + * listOrganizationProjects admin + * + * @remarks + * Lists projects belonging to an organization (admin view, no auth scoping). + */ + async listOrganizationProjects( + request: AdminListOrganizationProjectsRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminListOrganizationProjects( + this, + request, + options, + )); + } + + /** + * resumeStripeSubscription admin + * + * @remarks + * Removes a scheduled period-end cancellation from an organization's PAYG subscription. + */ + async resumeStripeSubscription( + request: ResumeStripeSubscriptionRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminResumeStripeSubscription( + this, + request, + options, + )); + } + + /** + * setInferenceKeyMonthlyLimit admin + * + * @remarks + * Sets the monthly limit for one materialized platform-managed OpenRouter key. + */ + async setInferenceKeyMonthlyLimit( + request: SetInferenceKeyMonthlyLimitRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminSetInferenceKeyMonthlyLimit( + this, + request, + options, + )); + } + + /** + * getStripeSubscription admin + * + * @remarks + * Returns the live Stripe subscription and payment state for an organization. + */ + async getStripeSubscription( + request: AdminGetStripeSubscriptionRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetStripeSubscription( + this, + request, + options, + )); + } + + /** + * updateOrganization admin + * + * @remarks + * Updates admin-managed fields on an organization. At least one of account_type or whitelisted must be supplied. + */ + async updateOrganization( + request: UpdateOrganizationRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminUpdateOrganization( + this, + request, + options, + )); + } + + /** + * bulkUpdateAccountType admin + * + * @remarks + * Sets one account type on many organizations in a single statement. An ID that matches no organization is reported back rather than failing the batch, so a stale ID costs the operator that row and not the whole call. + */ + async bulkUpdateAccountType( + request: BulkUpdateAccountTypeRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminBulkUpdateAccountType( + this, + request, + options, + )); + } + + /** + * listOrganizations admin + * + * @remarks + * Lists organizations for admin operations with optional search and filters. + */ + async listOrganizations( + request?: AdminListOrganizationsRequest | undefined, + options?: RequestOptions, + ): Promise> { + return unwrapResultIterator(adminListOrganizations( + this, + request, + options, + )); + } + + /** + * getOrganizationStats admin + * + * @remarks + * Returns platform-wide organization counts for the strip above the organizations list. Every figure counts the whole platform: none of them narrows to the caller's list filters, so the strip does not move when an operator filters. + */ + async getOrganizationStats( + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetOrganizationStats( + this, + options, + )); + } + + /** + * getProject admin + * + * @remarks + * Returns full admin details for a project by id or slug, including aggregated counts of child resources. + */ + async getProject( + request: AdminGetProjectRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetProject( + this, + request, + options, + )); + } + + /** + * getSession admin + */ + async getSession( + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminGetSession( + this, + options, + )); + } + + /** + * markEnterpriseTrialConverted admin + * + * @remarks + * Records that an organization's enterprise trial converted to a signed contract. + */ + async markEnterpriseTrialConverted( + request: MarkEnterpriseTrialConvertedRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminMarkEnterpriseTrialConverted( + this, + request, + options, + )); + } + + /** + * extendTrial admin + * + * @remarks + * Extends a running enterprise trial by adding days to its current end date. Only a running trial can be extended: one that has converted, has been demoted, or has already expired is rejected rather than re-armed. + */ + async extendTrial( + request: ExtendTrialRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminExtendTrial( + this, + request, + options, + )); + } + + /** + * rearmTrial admin + * + * @remarks + * Puts a demoted enterprise trial back on: restores the organization's account type and whitelist flag, revives its model provider keys, and gives the trial a fresh run of the given length counted from now. Only a demoted trial can be re-armed; one that has converted or is already running is rejected. + */ + async rearmTrial( + request: RearmTrialRequestBody, + options?: RequestOptions, + ): Promise { + return unwrapAsync(adminRearmTrial( + this, + request, + options, + )); + } +} diff --git a/client/admin/src/sdk/src/sdk/sdk.ts b/client/admin/src/sdk/src/sdk/sdk.ts new file mode 100644 index 00000000000..332e275cd44 --- /dev/null +++ b/client/admin/src/sdk/src/sdk/sdk.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ClientSDK } from "../lib/sdks.js"; +import { Admin } from "./admin.js"; + +export class Gram extends ClientSDK { + private _admin?: Admin; + get admin(): Admin { + return (this._admin ??= new Admin(this._options)); + } +} diff --git a/client/admin/src/sdk/src/types/async.ts b/client/admin/src/sdk/src/types/async.ts new file mode 100644 index 00000000000..1543b95cf7b --- /dev/null +++ b/client/admin/src/sdk/src/types/async.ts @@ -0,0 +1,69 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export type APICall = + | { + status: "complete"; + request: Request; + response: Response; + } + | { + status: "request-error"; + request: Request; + response?: undefined; + } + | { + status: "invalid"; + request?: undefined; + response?: undefined; + }; + +export class APIPromise implements Promise { + readonly #promise: Promise<[T, APICall]>; + #unwrapped: Promise | null; + + readonly [Symbol.toStringTag] = "APIPromise"; + + constructor(p: [T, APICall] | Promise<[T, APICall]>) { + this.#promise = p instanceof Promise ? p : Promise.resolve(p); + this.#unwrapped = p instanceof Promise ? null : Promise.resolve(p[0]); + } + + #getUnwrapped(): Promise { + return (this.#unwrapped ??= this.#promise.then(([value]) => value)); + } + + then( + onfulfilled?: + | ((value: T) => TResult1 | PromiseLike) + | null + | undefined, + onrejected?: + | ((reason: any) => TResult2 | PromiseLike) + | null + | undefined, + ): Promise { + return this.#promise.then( + onfulfilled ? ([value]) => onfulfilled(value) : void 0, + onrejected, + ); + } + + catch( + onrejected?: + | ((reason: any) => TResult | PromiseLike) + | null + | undefined, + ): Promise { + return this.#getUnwrapped().catch(onrejected); + } + + finally(onfinally?: (() => void) | null | undefined): Promise { + return this.#getUnwrapped().finally(onfinally); + } + + $inspect(): Promise<[T, APICall]> { + return this.#promise; + } +} diff --git a/client/admin/src/sdk/src/types/blobs.ts b/client/admin/src/sdk/src/types/blobs.ts new file mode 100644 index 00000000000..3deb988d444 --- /dev/null +++ b/client/admin/src/sdk/src/types/blobs.ts @@ -0,0 +1,33 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export const blobLikeSchema: z.ZodMiniType = z.custom( + isBlobLike, + { + message: "expected a Blob, File or Blob-like object", + abort: true, + }, +); + +export function isBlobLike(val: unknown): val is Blob { + if (val instanceof Blob) { + return true; + } + + if (typeof val !== "object" || val == null || !(Symbol.toStringTag in val)) { + return false; + } + + const name = val[Symbol.toStringTag]; + if (typeof name !== "string") { + return false; + } + if (name !== "Blob" && name !== "File") { + return false; + } + + return "stream" in val && typeof val.stream === "function"; +} diff --git a/client/admin/src/sdk/src/types/constdatetime.ts b/client/admin/src/sdk/src/types/constdatetime.ts new file mode 100644 index 00000000000..586ee46aa22 --- /dev/null +++ b/client/admin/src/sdk/src/types/constdatetime.ts @@ -0,0 +1,15 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; + +export function constDateTime( + val: string, +): z.ZodMiniType { + return z.custom((v) => { + return ( + typeof v === "string" && new Date(v).getTime() === new Date(val).getTime() + ); + }, `Value must be equivalent to ${val}`); +} diff --git a/client/admin/src/sdk/src/types/enums.ts b/client/admin/src/sdk/src/types/enums.ts new file mode 100644 index 00000000000..a523bdde4b5 --- /dev/null +++ b/client/admin/src/sdk/src/types/enums.ts @@ -0,0 +1,45 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod/v4-mini"; +import { Unrecognized, unrecognized } from "./unrecognized.js"; + +export type ClosedEnum>> = + T[keyof T]; +export type OpenEnum>> = + | T[keyof T] + | Unrecognized; + +export function inboundSchema>( + enumObj: T, +): z.ZodMiniType, unknown> { + const options = Object.values(enumObj); + return z.union([ + ...options.map(x => z.literal(x)), + z.pipe(z.string(), z.transform(x => unrecognized(x))), + ] as any); +} + +export function inboundSchemaInt>( + enumObj: T, +): z.ZodMiniType, unknown> { + // For numeric enums, Object.values returns both numbers and string keys + const options = Object.values(enumObj).filter(v => typeof v === "number"); + return z.union([ + ...options.map(x => z.literal(x)), + z.pipe(z.int(), z.transform(x => unrecognized(x))), + ] as any); +} + +export function outboundSchema>( + _: T, +): z.ZodMiniType> { + return z.string() as any; +} + +export function outboundSchemaInt>( + _: T, +): z.ZodMiniType> { + return z.int() as any; +} diff --git a/client/admin/src/sdk/src/types/fp.ts b/client/admin/src/sdk/src/types/fp.ts new file mode 100644 index 00000000000..ccbe51eac69 --- /dev/null +++ b/client/admin/src/sdk/src/types/fp.ts @@ -0,0 +1,50 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * A monad that captures the result of a function call or an error if it was not + * successful. Railway programming, enabled by this type, can be a nicer + * alternative to traditional exception throwing because it allows functions to + * declare all _known_ errors with static types and then check for them + * exhaustively in application code. Thrown exception have a type of `unknown` + * and break out of regular control flow of programs making them harder to + * inspect and more verbose work with due to try-catch blocks. + */ +export type Result = + | { ok: true; value: T; error?: never } + | { ok: false; value?: never; error: E }; + +export function OK(value: V): Result { + return { ok: true, value }; +} + +export function ERR(error: E): Result { + return { ok: false, error }; +} + +/** + * unwrap is a convenience function for extracting a value from a result or + * throwing if there was an error. + */ +export function unwrap(r: Result): T { + if (!r.ok) { + throw r.error; + } + return r.value; +} + +/** + * unwrapAsync is a convenience function for resolving a value from a Promise + * of a result or rejecting if an error occurred. + */ +export async function unwrapAsync( + pr: Promise>, +): Promise { + const r = await pr; + if (!r.ok) { + throw r.error; + } + + return r.value; +} diff --git a/client/admin/src/sdk/src/types/operations.ts b/client/admin/src/sdk/src/types/operations.ts new file mode 100644 index 00000000000..beb81e10f0b --- /dev/null +++ b/client/admin/src/sdk/src/types/operations.ts @@ -0,0 +1,105 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { Result } from "./fp.js"; + +export type Paginator = () => Promise }> | null; + +export type PageIterator = V & { + next: Paginator; + [Symbol.asyncIterator]: () => AsyncIterableIterator; + "~next"?: PageState | undefined; +}; + +export function createPageIterator( + page: V & { next: Paginator }, + halt: (v: V) => boolean, +): { + [Symbol.asyncIterator]: () => AsyncIterableIterator; +} { + return { + [Symbol.asyncIterator]: async function* paginator() { + yield page; + if (halt(page)) { + return; + } + + let p: typeof page | null = page; + for (p = await p.next(); p != null; p = await p.next()) { + yield p; + if (halt(p)) { + return; + } + } + }, + }; +} + +/** + * This utility create a special iterator that yields a single value and + * terminates. It is useful in paginated SDK functions that have early return + * paths when things go wrong. + */ +export function haltIterator( + v: V, +): PageIterator { + return { + ...v, + next: () => null, + [Symbol.asyncIterator]: async function* paginator() { + yield v; + }, + }; +} + +/** + * Converts an async iterator of `Result` into an async iterator of `V`. + * When error results occur, the underlying error value is thrown. + */ +export async function unwrapResultIterator( + iteratorPromise: Promise, PageState>>, +): Promise> { + const resultIter = await iteratorPromise; + + if (!resultIter.ok) { + throw resultIter.error; + } + + return { + ...resultIter.value, + next: unwrapPaginator(resultIter.next), + "~next": resultIter["~next"], + [Symbol.asyncIterator]: async function* paginator() { + for await (const page of resultIter) { + if (!page.ok) { + throw page.error; + } + yield page.value; + } + }, + }; +} + +function unwrapPaginator( + paginator: Paginator>, +): Paginator { + return () => { + const nextResult = paginator(); + if (nextResult == null) { + return null; + } + return nextResult.then((res) => { + if (!res.ok) { + throw res.error; + } + const out = { + ...res.value, + next: unwrapPaginator(res.next), + }; + return out; + }); + }; +} + +export const URL_OVERRIDE = Symbol("URL_OVERRIDE"); diff --git a/client/admin/src/sdk/src/types/rfcdate.ts b/client/admin/src/sdk/src/types/rfcdate.ts new file mode 100644 index 00000000000..c79b3f53a3d --- /dev/null +++ b/client/admin/src/sdk/src/types/rfcdate.ts @@ -0,0 +1,54 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +const dateRE = /^\d{4}-\d{2}-\d{2}$/; + +export class RFCDate { + private serialized: string; + + /** + * Creates a new RFCDate instance using today's date. + */ + static today(): RFCDate { + return new RFCDate(new Date()); + } + + /** + * Creates a new RFCDate instance using the provided input. + * If a string is used then in must be in the format YYYY-MM-DD. + * + * @param date A Date object or a date string in YYYY-MM-DD format + * @example + * new RFCDate("2022-01-01") + * @example + * new RFCDate(new Date()) + */ + constructor(date: Date | string) { + if (typeof date === "string" && !dateRE.test(date)) { + throw new RangeError( + "RFCDate: date strings must be in the format YYYY-MM-DD: " + date, + ); + } + + const value = new Date(date); + if (isNaN(+value)) { + throw new RangeError("RFCDate: invalid date provided: " + date); + } + + this.serialized = value.toISOString().slice(0, "YYYY-MM-DD".length); + if (!dateRE.test(this.serialized)) { + throw new TypeError( + `RFCDate: failed to build valid date with given value: ${date} serialized to ${this.serialized}`, + ); + } + } + + toJSON(): string { + return this.toString(); + } + + toString(): string { + return this.serialized; + } +} diff --git a/client/admin/src/sdk/src/types/streams.ts b/client/admin/src/sdk/src/types/streams.ts new file mode 100644 index 00000000000..a0163e7a99c --- /dev/null +++ b/client/admin/src/sdk/src/types/streams.ts @@ -0,0 +1,21 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export function isReadableStream( + val: unknown, +): val is ReadableStream { + if (typeof val !== "object" || val === null) { + return false; + } + + // Check for the presence of methods specific to ReadableStream + const stream = val as ReadableStream; + + // ReadableStream has methods like getReader, cancel, and tee + return ( + typeof stream.getReader === "function" && + typeof stream.cancel === "function" && + typeof stream.tee === "function" + ); +} diff --git a/client/admin/src/sdk/src/types/unrecognized.ts b/client/admin/src/sdk/src/types/unrecognized.ts new file mode 100644 index 00000000000..b7a2a13f3df --- /dev/null +++ b/client/admin/src/sdk/src/types/unrecognized.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +declare const __brand: unique symbol; +export type Unrecognized = T & { [__brand]: "unrecognized" }; + +function unrecognized(value: T): Unrecognized { + globalCount++; + return value as Unrecognized; +} + +let globalCount = 0; +let refCount = 0; +export function startCountingUnrecognized() { + refCount++; + const start = globalCount; + return { + /** + * Ends counting and returns the delta. + * @param delta - If provided, only this amount is added to the parent counter + * (used for nested unions where we only want to record the winning option's count). + * If not provided, records all counts since start(). + */ + end: (delta?: number) => { + const count = globalCount - start; + // Reset globalCount back to start, then add only the specified delta + globalCount = start + (delta ?? count); + if (--refCount === 0) globalCount = 0; + return count; + }, + }; +} + +export { unrecognized }; diff --git a/client/admin/tsconfig.app.json b/client/admin/tsconfig.app.json index 917bd23aaa2..b4cf77ea825 100644 --- a/client/admin/tsconfig.app.json +++ b/client/admin/tsconfig.app.json @@ -18,7 +18,9 @@ "jsx": "react-jsx", "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@gram/admin-client": ["./src/sdk/src/index.ts"], + "@gram/admin-client/*": ["./src/sdk/src/*"] }, /* Dead-code guards */ diff --git a/client/admin/tsconfig.json b/client/admin/tsconfig.json index 28165c937e1..16467e72dba 100644 --- a/client/admin/tsconfig.json +++ b/client/admin/tsconfig.json @@ -7,7 +7,9 @@ ], "compilerOptions": { "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@gram/admin-client": ["./src/sdk/src/index.ts"], + "@gram/admin-client/*": ["./src/sdk/src/*"] } } } diff --git a/client/admin/vite.config.ts b/client/admin/vite.config.ts index 8cd3c90e3f5..912fa624a62 100644 --- a/client/admin/vite.config.ts +++ b/client/admin/vite.config.ts @@ -93,6 +93,7 @@ export default defineConfig(({ command }) => { resolve: { alias: { "@": path.resolve(__dirname, "./src"), + "@gram/admin-client": path.resolve(__dirname, "./src/sdk/src"), }, }, server: { diff --git a/client/admin/vitest.config.ts b/client/admin/vitest.config.ts index 11592bc3f99..7f0d0395a56 100644 --- a/client/admin/vitest.config.ts +++ b/client/admin/vitest.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve(__dirname, "./src"), + "@gram/admin-client": path.resolve(__dirname, "./src/sdk/src"), }, }, test: { diff --git a/overlays/admin-sdk.yaml b/overlays/admin-sdk.yaml new file mode 100644 index 00000000000..b0934c49321 --- /dev/null +++ b/overlays/admin-sdk.yaml @@ -0,0 +1,116 @@ +overlay: 1.0.0 +x-speakeasy-jsonpath: rfc9535 +info: + title: Admin SDK policy + version: 0.0.0 +actions: + # Retain only operations owned by the standalone Admin service. + - target: $.paths.*[?count(@.tags[?@=='admin'])==0] + remove: true + - target: $.paths[?length(@)==0] + remove: true + - target: $.tags[?@.name!='admin'] + remove: true + # Browser requests authenticate with the ambient same-origin Admin cookie. + - target: $.paths..security + remove: true + - target: $.components.securitySchemes["admin_auth_header_Authorization"] + remove: true + - target: $.servers[0].url + update: / + # Goa's service-method separator is not a valid generated operation name. + - target: $.paths.*[?@.operationId=='admin#logout'] + update: + operationId: adminLogout + x-speakeasy-name-override: logout + # Keep resource-local SDK methods from repeating the admin namespace. + - target: $.paths.*[?@.operationId=='adminBulkUpdateAccountType'] + update: + x-speakeasy-name-override: bulkUpdateAccountType + - target: $.paths.*[?@.operationId=='adminCancelStripeSubscription'] + update: + x-speakeasy-name-override: cancelStripeSubscription + - target: $.paths.*[?@.operationId=='adminCreateOrganization'] + update: + x-speakeasy-name-override: createOrganization + - target: $.paths.*[?@.operationId=='adminDisableOrganization'] + update: + x-speakeasy-name-override: disableOrganization + - target: $.paths.*[?@.operationId=='adminEnableOrganization'] + update: + x-speakeasy-name-override: enableOrganization + - target: $.paths.*[?@.operationId=='adminExtendTrial'] + update: + x-speakeasy-name-override: extendTrial + - target: $.paths.*[?@.operationId=='adminGetInferenceKeys'] + update: + x-speakeasy-name-override: getInferenceKeys + - target: $.paths.*[?@.operationId=='adminGetInferenceSpendHistory'] + update: + x-speakeasy-name-override: getInferenceSpendHistory + - target: $.paths.*[?@.operationId=='adminGetOrganization'] + update: + x-speakeasy-name-override: getOrganization + - target: $.paths.*[?@.operationId=='adminGetOrganizationChatAnalysisSettings'] + update: + x-speakeasy-name-override: getOrganizationChatAnalysisSettings + - target: $.paths.*[?@.operationId=='adminGetOrganizationFeatures'] + update: + x-speakeasy-name-override: getOrganizationFeatures + - target: $.paths.*[?@.operationId=='adminGetOrganizationStats'] + update: + x-speakeasy-name-override: getOrganizationStats + - target: $.paths.*[?@.operationId=='adminGetPaygBillingSummary'] + update: + x-speakeasy-name-override: getPaygBillingSummary + - target: $.paths.*[?@.operationId=='adminGetProject'] + update: + x-speakeasy-name-override: getProject + - target: $.paths.*[?@.operationId=='adminGetSession'] + update: + x-speakeasy-name-override: getSession + - target: $.paths.*[?@.operationId=='adminGetStripeSubscription'] + update: + x-speakeasy-name-override: getStripeSubscription + - target: $.paths.*[?@.operationId=='adminListOrganizationActivity'] + update: + x-speakeasy-name-override: listOrganizationActivity + - target: $.paths.*[?@.operationId=='adminListOrganizationMembers'] + update: + x-speakeasy-name-override: listOrganizationMembers + - target: $.paths.*[?@.operationId=='adminListOrganizationProjects'] + update: + x-speakeasy-name-override: listOrganizationProjects + - target: $.paths.*[?@.operationId=='adminListOrganizations'] + update: + x-speakeasy-name-override: listOrganizations + - target: $.paths.*[?@.operationId=='adminMarkEnterpriseTrialConverted'] + update: + x-speakeasy-name-override: markEnterpriseTrialConverted + - target: $.paths.*[?@.operationId=='adminRearmTrial'] + update: + x-speakeasy-name-override: rearmTrial + - target: $.paths.*[?@.operationId=='adminResumeStripeSubscription'] + update: + x-speakeasy-name-override: resumeStripeSubscription + - target: $.paths.*[?@.operationId=='adminSetInferenceKeyMonthlyLimit'] + update: + x-speakeasy-name-override: setInferenceKeyMonthlyLimit + - target: $.paths.*[?@.operationId=='adminSetOrganizationChatAnalysisSettings'] + update: + x-speakeasy-name-override: setOrganizationChatAnalysisSettings + - target: $.paths.*[?@.operationId=='adminSetOrganizationFeature'] + update: + x-speakeasy-name-override: setOrganizationFeature + - target: $.paths.*[?@.operationId=='adminTriggerOrganizationChatAnalysis'] + update: + x-speakeasy-name-override: triggerOrganizationChatAnalysis + - target: $.paths.*[?@.operationId=='adminUpdateOrganization'] + update: + x-speakeasy-name-override: updateOrganization + - target: $.paths.*[?@.operationId=='adminLogout'].parameters[?@.in=='cookie'] + remove: true + # These operations navigate the browser rather than making SDK requests. + - target: $.paths.*[?(@.operationId=='admin#login' || @.operationId=='admin#callback' || @.operationId=='adminOpenOrganizationInDashboard')] + update: + x-speakeasy-ignore: true diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb30e8c4b5f..25a75c1ff99 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,6 +146,9 @@ importers: tw-animate-css: specifier: ^1.4.0 version: 1.4.0 + zod: + specifier: ^4 + version: 4.4.3 devDependencies: '@tanstack/router-plugin': specifier: 1.168.30 diff --git a/server/internal/admin/generated_routes_test.go b/server/internal/admin/generated_routes_test.go index dc7ba4b55a7..00065ff23f5 100644 --- a/server/internal/admin/generated_routes_test.go +++ b/server/internal/admin/generated_routes_test.go @@ -117,7 +117,7 @@ func TestGeneratedAdminRoutes_AuthenticateBeforeDecode(t *testing.T) { rec := httptest.NewRecorder() SessionMiddleware(mux).ServeHTTP(rec, req) require.Equal(t, http.StatusBadRequest, rec.Code) - require.Equal(t, 1, userinfoCalls, "successful pre-decode verification must be reused by Goa auth") + require.Equal(t, 1, userinfoCalls, "session must be verified before decoding the request body") } func TestGeneratedAdminRoutes_RejectOversizedJSONBody(t *testing.T) {