mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-03 20:39:33 -05:00
Merge 7883c7e997 into 3e568fc81b
This commit is contained in:
commit
f2c7ebaa4e
14 changed files with 1004 additions and 53 deletions
2
.github/workflows/js-ci.yml
vendored
2
.github/workflows/js-ci.yml
vendored
|
|
@ -169,7 +169,7 @@ jobs:
|
|||
- name: Start Keycloak server
|
||||
run: |
|
||||
tar xfvz keycloak-999.0.0-SNAPSHOT.tar.gz
|
||||
keycloak-999.0.0-SNAPSHOT/bin/kc.sh start-dev --features=transient-users,oid4vc-vci &> ~/server.log &
|
||||
keycloak-999.0.0-SNAPSHOT/bin/kc.sh start-dev --features=transient-users,oid4vc-vci,client-admin-api:v2 &> ~/server.log &
|
||||
env:
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME: admin
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ async function startServer() {
|
|||
path.join(SERVER_DIR, `bin/kc${SCRIPT_EXTENSION}`),
|
||||
[
|
||||
"start-dev",
|
||||
`--features="transient-users,oid4vc-vci,declarative-ui,quick-theme,spiffe,kubernetes-service-accounts,workflows,client-auth-federated,jwt-authorization-grant"`,
|
||||
`--features="transient-users,oid4vc-vci,declarative-ui,quick-theme,spiffe,kubernetes-service-accounts,workflows,client-auth-federated,openapi,client-admin-api:v2"`,
|
||||
"--openapi-enabled=true",
|
||||
...keycloakArgs,
|
||||
],
|
||||
{
|
||||
|
|
|
|||
2
js/libs/keycloak-admin-client/.gitignore
vendored
2
js/libs/keycloak-admin-client/.gitignore
vendored
|
|
@ -1 +1,3 @@
|
|||
lib/
|
||||
generated/
|
||||
.kiota/
|
||||
|
|
|
|||
257
js/libs/keycloak-admin-client/api.yml
Normal file
257
js/libs/keycloak-admin-client/api.yml
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
---
|
||||
openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
Auth:
|
||||
type: object
|
||||
properties:
|
||||
method:
|
||||
type: string
|
||||
secret:
|
||||
type: string
|
||||
certificate:
|
||||
type: string
|
||||
BaseClientRepresentation:
|
||||
type: object
|
||||
properties:
|
||||
clientId:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
appUrl:
|
||||
type: string
|
||||
redirectUris:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
roles:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
additionalFields:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
Flow:
|
||||
type: string
|
||||
enum:
|
||||
- STANDARD
|
||||
- IMPLICIT
|
||||
- DIRECT_GRANT
|
||||
- SERVICE_ACCOUNT
|
||||
- TOKEN_EXCHANGE
|
||||
- DEVICE
|
||||
- CIBA
|
||||
OIDCClientRepresentation:
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseClientRepresentation"
|
||||
properties:
|
||||
loginFlows:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Flow"
|
||||
auth:
|
||||
$ref: "#/components/schemas/Auth"
|
||||
webOrigins:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
serviceAccountRoles:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
protocol:
|
||||
type: string
|
||||
SAMLClientRepresentation:
|
||||
type: object
|
||||
description: SAML Client configuration
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseClientRepresentation"
|
||||
properties:
|
||||
nameIdFormat:
|
||||
type: string
|
||||
forceNameIdFormat:
|
||||
type: boolean
|
||||
includeAuthnStatement:
|
||||
type: boolean
|
||||
signDocuments:
|
||||
type: boolean
|
||||
signAssertions:
|
||||
type: boolean
|
||||
clientSignatureRequired:
|
||||
type: boolean
|
||||
forcePostBinding:
|
||||
type: boolean
|
||||
frontChannelLogout:
|
||||
type: boolean
|
||||
signatureAlgorithm:
|
||||
type: string
|
||||
signatureCanonicalizationMethod:
|
||||
type: string
|
||||
signingCertificate:
|
||||
type: string
|
||||
allowEcpFlow:
|
||||
type: boolean
|
||||
protocol:
|
||||
type: string
|
||||
tags:
|
||||
- name: Clients (v2)
|
||||
x-smallrye-profile-admin: ""
|
||||
paths:
|
||||
/admin/api/{realmName}/clients/{version}:
|
||||
get:
|
||||
summary: Get all clients
|
||||
description: Returns a list of all clients in the realm
|
||||
tags:
|
||||
- Clients (v2)
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/OIDCClientRepresentation"
|
||||
- $ref: "#/components/schemas/SAMLClientRepresentation"
|
||||
discriminator:
|
||||
propertyName: protocol
|
||||
mapping:
|
||||
openid-connect: "#/components/schemas/OIDCClientRepresentation"
|
||||
saml: "#/components/schemas/SAMLClientRepresentation"
|
||||
post:
|
||||
summary: Create a new client
|
||||
description: Creates a new client in the realm
|
||||
tags:
|
||||
- Clients (v2)
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/OIDCClientRepresentation"
|
||||
- $ref: "#/components/schemas/SAMLClientRepresentation"
|
||||
discriminator:
|
||||
propertyName: protocol
|
||||
mapping:
|
||||
openid-connect: "#/components/schemas/OIDCClientRepresentation"
|
||||
saml: "#/components/schemas/SAMLClientRepresentation"
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
parameters:
|
||||
- name: realmName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: version
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
pattern: v\d+
|
||||
/admin/api/{realmName}/clients/{version}/{id}:
|
||||
get:
|
||||
tags:
|
||||
- Clients (v2)
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/OIDCClientRepresentation"
|
||||
- $ref: "#/components/schemas/SAMLClientRepresentation"
|
||||
discriminator:
|
||||
propertyName: protocol
|
||||
mapping:
|
||||
openid-connect: "#/components/schemas/OIDCClientRepresentation"
|
||||
saml: "#/components/schemas/SAMLClientRepresentation"
|
||||
put:
|
||||
tags:
|
||||
- Clients (v2)
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/OIDCClientRepresentation"
|
||||
- $ref: "#/components/schemas/SAMLClientRepresentation"
|
||||
discriminator:
|
||||
propertyName: protocol
|
||||
mapping:
|
||||
openid-connect: "#/components/schemas/OIDCClientRepresentation"
|
||||
saml: "#/components/schemas/SAMLClientRepresentation"
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
patch:
|
||||
tags:
|
||||
- Clients (v2)
|
||||
requestBody:
|
||||
content:
|
||||
application/merge-patch+json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: "#/components/schemas/OIDCClientRepresentation"
|
||||
- $ref: "#/components/schemas/SAMLClientRepresentation"
|
||||
discriminator:
|
||||
propertyName: protocol
|
||||
mapping:
|
||||
openid-connect: "#/components/schemas/OIDCClientRepresentation"
|
||||
saml: "#/components/schemas/SAMLClientRepresentation"
|
||||
delete:
|
||||
tags:
|
||||
- Clients (v2)
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
parameters:
|
||||
- name: realmName
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: version
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
pattern: v\d+
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
info:
|
||||
title: Keycloak API
|
||||
version: 999.0.0-SNAPSHOT
|
||||
181
js/libs/keycloak-admin-client/generate.ts
Normal file
181
js/libs/keycloak-admin-client/generate.ts
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
// Use require for CommonJS compatibility with @microsoft/kiota
|
||||
// The ESM build of @microsoft/kiota is broken (missing files), so we use require()
|
||||
import { createRequire } from "module";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname, resolve } from "path";
|
||||
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const {
|
||||
generateClient,
|
||||
KiotaGenerationLanguage,
|
||||
ConsumerOperation,
|
||||
} = require("@microsoft/kiota");
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const projectRoot = resolve(__dirname, ".");
|
||||
|
||||
// Configuration
|
||||
const OPENAPI_URL = process.env.OPENAPI_URL || "http://localhost:9000/openapi";
|
||||
const OPENAPI_FILE = process.env.OPENAPI_FILE; // Optional: use a local file instead
|
||||
const OUTPUT_PATH = resolve(projectRoot, "src/generated");
|
||||
const CLIENT_CLASS_NAME = "AdminClient";
|
||||
const CLIENT_NAMESPACE = "ApiSdk";
|
||||
|
||||
async function downloadOpenApiSpec(url: string): Promise<string> {
|
||||
console.log(`📥 Downloading OpenAPI spec from ${url}...`);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to download OpenAPI spec: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
const content = await response.text();
|
||||
|
||||
// Save to a temp file
|
||||
const tempFile = resolve(projectRoot, ".openapi-temp.yaml");
|
||||
writeFileSync(tempFile, content);
|
||||
console.log(`✅ Downloaded and saved to ${tempFile}`);
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("🚀 Keycloak Admin Client v2 - Kiota Generator\n");
|
||||
|
||||
let openApiFilePath: string;
|
||||
|
||||
if (OPENAPI_FILE) {
|
||||
// Use local file
|
||||
openApiFilePath = resolve(projectRoot, OPENAPI_FILE);
|
||||
if (!existsSync(openApiFilePath)) {
|
||||
console.error(`❌ OpenAPI file not found: ${openApiFilePath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`📄 Using local OpenAPI file: ${openApiFilePath}`);
|
||||
} else {
|
||||
// Download from URL
|
||||
openApiFilePath = await downloadOpenApiSpec(OPENAPI_URL);
|
||||
}
|
||||
|
||||
// Ensure output directory exists
|
||||
if (!existsSync(OUTPUT_PATH)) {
|
||||
mkdirSync(OUTPUT_PATH, { recursive: true });
|
||||
}
|
||||
|
||||
console.log(`\n📦 Generating TypeScript client...`);
|
||||
console.log(` Output: ${OUTPUT_PATH}`);
|
||||
console.log(` Client class: ${CLIENT_CLASS_NAME}`);
|
||||
console.log(` Namespace: ${CLIENT_NAMESPACE}\n`);
|
||||
|
||||
try {
|
||||
const result = await generateClient({
|
||||
openAPIFilePath: openApiFilePath,
|
||||
clientClassName: CLIENT_CLASS_NAME,
|
||||
clientNamespaceName: CLIENT_NAMESPACE,
|
||||
language: KiotaGenerationLanguage.TypeScript,
|
||||
outputPath: OUTPUT_PATH,
|
||||
operation: ConsumerOperation.Generate,
|
||||
workingDirectory: projectRoot,
|
||||
cleanOutput: true,
|
||||
});
|
||||
|
||||
if (result) {
|
||||
console.log("\n✅ Client generated successfully!");
|
||||
|
||||
if (result.logs && result.logs.length > 0) {
|
||||
console.log("\n📋 Generation logs:");
|
||||
for (const log of result.logs) {
|
||||
const level = log.level === 1 ? "⚠️" : log.level === 2 ? "❌" : "ℹ️";
|
||||
console.log(` ${level} ${log.message}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("\n⚠️ Generation completed but returned no result");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("\n❌ Generation failed:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Post-process: Fix empty if blocks in adminClient.ts that cause TS2774 errors
|
||||
postProcessGeneratedCode();
|
||||
|
||||
console.log("\n🎉 Done! You can now build the project with: npm run build");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix known issues in Kiota-generated code
|
||||
*/
|
||||
function postProcessGeneratedCode() {
|
||||
const adminClientPath = resolve(OUTPUT_PATH, "adminClient.ts");
|
||||
|
||||
if (!existsSync(adminClientPath)) {
|
||||
console.log("⚠️ adminClient.ts not found, skipping post-processing");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("\n🔧 Post-processing generated code...");
|
||||
|
||||
let content = readFileSync(adminClientPath, "utf-8");
|
||||
let modified = false;
|
||||
|
||||
// The Kiota npm package generates empty if-blocks for serializer registration
|
||||
// We need to fill them in with the actual registration calls
|
||||
|
||||
// Check if the if-blocks are empty (missing the registration calls)
|
||||
if (
|
||||
content.includes(
|
||||
"if (parseNodeFactoryRegistry.registerDefaultDeserializer) {\n }",
|
||||
)
|
||||
) {
|
||||
// Add required imports for serializers/deserializers
|
||||
const serializerImports = `// @ts-ignore
|
||||
import { FormParseNodeFactory, FormSerializationWriterFactory } from '@microsoft/kiota-serialization-form';
|
||||
// @ts-ignore
|
||||
import { JsonParseNodeFactory, JsonSerializationWriterFactory } from '@microsoft/kiota-serialization-json';
|
||||
// @ts-ignore
|
||||
import { MultipartSerializationWriterFactory } from '@microsoft/kiota-serialization-multipart';
|
||||
// @ts-ignore
|
||||
import { TextParseNodeFactory, TextSerializationWriterFactory } from '@microsoft/kiota-serialization-text';
|
||||
`;
|
||||
|
||||
// Add imports after the existing imports
|
||||
content = content.replace(
|
||||
/import \{ apiClientProxifier,/,
|
||||
serializerImports + "\nimport { apiClientProxifier,",
|
||||
);
|
||||
|
||||
// Fill in the deserializer registration
|
||||
content = content.replace(
|
||||
/if \(parseNodeFactoryRegistry\.registerDefaultDeserializer\) \{\n {4}\}/,
|
||||
`if (parseNodeFactoryRegistry.registerDefaultDeserializer) {
|
||||
parseNodeFactoryRegistry.registerDefaultDeserializer(JsonParseNodeFactory, backingStoreFactory);
|
||||
parseNodeFactoryRegistry.registerDefaultDeserializer(TextParseNodeFactory, backingStoreFactory);
|
||||
parseNodeFactoryRegistry.registerDefaultDeserializer(FormParseNodeFactory, backingStoreFactory);
|
||||
}`,
|
||||
);
|
||||
|
||||
// Fill in the serializer registration
|
||||
content = content.replace(
|
||||
/if \(serializationWriterFactory\.registerDefaultSerializer\) \{\n {4}\}/,
|
||||
`if (serializationWriterFactory.registerDefaultSerializer) {
|
||||
serializationWriterFactory.registerDefaultSerializer(JsonSerializationWriterFactory);
|
||||
serializationWriterFactory.registerDefaultSerializer(TextSerializationWriterFactory);
|
||||
serializationWriterFactory.registerDefaultSerializer(FormSerializationWriterFactory);
|
||||
serializationWriterFactory.registerDefaultSerializer(MultipartSerializationWriterFactory);
|
||||
}`,
|
||||
);
|
||||
|
||||
modified = true;
|
||||
console.log(" ✅ Added serializer/deserializer registration code");
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
writeFileSync(adminClientPath, content);
|
||||
} else {
|
||||
console.log(" ℹ️ No fixes needed");
|
||||
}
|
||||
}
|
||||
|
||||
void main();
|
||||
|
|
@ -18,11 +18,16 @@
|
|||
"build": "wireit",
|
||||
"lint": "wireit",
|
||||
"test": "wireit",
|
||||
"generate:openapi": "wireit",
|
||||
"postinstall": "pnpm generate:openapi",
|
||||
"prepublishOnly": "pnpm build"
|
||||
},
|
||||
"wireit": {
|
||||
"build": {
|
||||
"command": "tsc --pretty",
|
||||
"dependencies": [
|
||||
"generate:openapi"
|
||||
],
|
||||
"files": [
|
||||
"src",
|
||||
"tsconfig.json"
|
||||
|
|
@ -31,6 +36,15 @@
|
|||
"lib"
|
||||
]
|
||||
},
|
||||
"generate:openapi": {
|
||||
"command": "OPENAPI_FILE=api.yml tsx generate.ts",
|
||||
"files": [
|
||||
"api.yml"
|
||||
],
|
||||
"output": [
|
||||
"src/generated"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"command": "eslint ."
|
||||
},
|
||||
|
|
@ -39,11 +53,18 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/kiota-abstractions": "^1.0.0-preview.86",
|
||||
"@microsoft/kiota-http-fetchlibrary": "^1.0.0-preview.80",
|
||||
"@microsoft/kiota-serialization-form": "^1.0.0-preview.74",
|
||||
"@microsoft/kiota-serialization-json": "^1.0.0-preview.86",
|
||||
"@microsoft/kiota-serialization-multipart": "^1.0.0-preview.67",
|
||||
"@microsoft/kiota-serialization-text": "^1.0.0-preview.79",
|
||||
"camelize-ts": "^3.0.0",
|
||||
"url-template": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^10.2.0",
|
||||
"@microsoft/kiota": "^1.29.0",
|
||||
"@types/chai": "^5.2.2",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mocha": "^10.0.10",
|
||||
|
|
@ -51,7 +72,8 @@
|
|||
"chai": "^6.2.2",
|
||||
"lodash-es": "^4.17.23",
|
||||
"mocha": "^11.7.5",
|
||||
"ts-node": "^10.9.2"
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.19.2"
|
||||
},
|
||||
"author": {
|
||||
"name": "Red Hat, Inc.",
|
||||
|
|
|
|||
|
|
@ -8,3 +8,10 @@ export type { NetworkErrorOptions } from "./utils/fetchWithError.js";
|
|||
|
||||
export type { default as OrganizationInvitationRepresentation } from "./defs/organizationInvitationRepresentation.js";
|
||||
export { OrganizationInvitationStatus } from "./defs/organizationInvitationRepresentation.js";
|
||||
|
||||
// V2 API types (Kiota-generated)
|
||||
export type {
|
||||
OIDCClientRepresentation,
|
||||
SAMLClientRepresentation,
|
||||
ClientRepresentationV2,
|
||||
} from "./resources/clientsV2.js";
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import type ScopeRepresentation from "../defs/scopeRepresentation.js";
|
|||
import type UserRepresentation from "../defs/userRepresentation.js";
|
||||
import type UserSessionRepresentation from "../defs/userSessionRepresentation.js";
|
||||
import Resource from "./resource.js";
|
||||
import { ClientsV2 } from "./clientsV2.js";
|
||||
|
||||
export interface PaginatedQuery {
|
||||
first?: number;
|
||||
|
|
@ -53,6 +54,11 @@ export interface PolicyQuery extends PaginatedQuery {
|
|||
}
|
||||
|
||||
export class Clients extends Resource<{ realm?: string }> {
|
||||
/**
|
||||
* Clients v2 API - New versioned API with OpenAPI-generated client.
|
||||
*/
|
||||
#v2: ClientsV2;
|
||||
|
||||
public find = this.makeRequest<ClientQuery, ClientRepresentation[]>({
|
||||
method: "GET",
|
||||
});
|
||||
|
|
@ -1055,6 +1061,45 @@ export class Clients extends Resource<{ realm?: string }> {
|
|||
}),
|
||||
getBaseUrl: () => client.baseUrl,
|
||||
});
|
||||
|
||||
// Initialize v2 API
|
||||
this.#v2 = new ClientsV2(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clients v2 API endpoint for the currently configured realm.
|
||||
* Returns a fluent API builder for client operations using the new versioned API.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // List all clients
|
||||
* const clients = await kcAdminClient.clients.v2().get();
|
||||
*
|
||||
* // Get a single client by clientId
|
||||
* const client = await kcAdminClient.clients.v2().byId("my-client").get();
|
||||
*
|
||||
* // Create a new client
|
||||
* await kcAdminClient.clients.v2().post({
|
||||
* clientId: "my-client",
|
||||
* protocol: "openid-connect",
|
||||
* enabled: true,
|
||||
* });
|
||||
*
|
||||
* // Update a client
|
||||
* await kcAdminClient.clients.v2().byId("my-client").put({
|
||||
* clientId: "my-client",
|
||||
* protocol: "openid-connect",
|
||||
* description: "Updated description",
|
||||
* });
|
||||
*
|
||||
* // Delete a client
|
||||
* await kcAdminClient.clients.v2().byId("my-client").delete();
|
||||
* ```
|
||||
*
|
||||
* @returns A promise that resolves to the clients v2 endpoint
|
||||
*/
|
||||
v2() {
|
||||
return this.#v2.api();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
74
js/libs/keycloak-admin-client/src/resources/clientsV2.ts
Normal file
74
js/libs/keycloak-admin-client/src/resources/clientsV2.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import {
|
||||
type AuthenticationProvider,
|
||||
type RequestInformation,
|
||||
} from "@microsoft/kiota-abstractions";
|
||||
import { FetchRequestAdapter } from "@microsoft/kiota-http-fetchlibrary";
|
||||
|
||||
import type { KeycloakAdminClient } from "../client.js";
|
||||
import { createAdminClient } from "../generated/adminClient.js";
|
||||
import type { WithVersionItemRequestBuilder } from "../generated/admin/api/item/clients/item/index.js";
|
||||
|
||||
// Re-export types for convenience
|
||||
export type {
|
||||
OIDCClientRepresentation,
|
||||
SAMLClientRepresentation,
|
||||
} from "../generated/models/index.js";
|
||||
|
||||
export type ClientRepresentationV2 =
|
||||
| import("../generated/models/index.js").OIDCClientRepresentation
|
||||
| import("../generated/models/index.js").SAMLClientRepresentation;
|
||||
|
||||
/**
|
||||
* Authentication provider for Keycloak Admin Client that adds Bearer token to requests.
|
||||
*/
|
||||
class KeycloakAuthProvider implements AuthenticationProvider {
|
||||
#getAccessToken: () => Promise<string | undefined>;
|
||||
|
||||
constructor(getAccessToken: () => Promise<string | undefined>) {
|
||||
this.#getAccessToken = getAccessToken;
|
||||
}
|
||||
|
||||
async authenticateRequest(request: RequestInformation): Promise<void> {
|
||||
const token = await this.#getAccessToken();
|
||||
if (token) {
|
||||
request.headers.add("Authorization", `Bearer ${token}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clients v2 endpoint configured with the KeycloakAdminClient's
|
||||
* base URL, access token, and realm.
|
||||
*/
|
||||
function createClientsV2Endpoint(
|
||||
client: KeycloakAdminClient,
|
||||
): WithVersionItemRequestBuilder {
|
||||
const authProvider = new KeycloakAuthProvider(() => client.getAccessToken());
|
||||
const adapter = new FetchRequestAdapter(authProvider);
|
||||
adapter.baseUrl = client.baseUrl;
|
||||
|
||||
const adminClient = createAdminClient(adapter);
|
||||
return adminClient.admin.api.byRealmName(client.realmName).clients.byVersion("v2");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clients v2 API resource.
|
||||
* Provides access to the new versioned clients API using the configured realm.
|
||||
*/
|
||||
export class ClientsV2 {
|
||||
#client: KeycloakAdminClient;
|
||||
|
||||
constructor(client: KeycloakAdminClient) {
|
||||
this.#client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clients v2 endpoint for the currently configured realm.
|
||||
* Returns a fluent API builder for client operations.
|
||||
*
|
||||
* @returns The clients v2 endpoint
|
||||
*/
|
||||
api(): WithVersionItemRequestBuilder {
|
||||
return createClientsV2Endpoint(this.#client);
|
||||
}
|
||||
}
|
||||
151
js/libs/keycloak-admin-client/test/clientsV2.spec.ts
Normal file
151
js/libs/keycloak-admin-client/test/clientsV2.spec.ts
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
import { faker } from "@faker-js/faker";
|
||||
import * as chai from "chai";
|
||||
import { KeycloakAdminClient } from "../src/client.js";
|
||||
import type { OIDCClientRepresentation } from "../src/generated/models/index.js";
|
||||
import { credentials } from "./constants.js";
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
describe("Clients V2 API", () => {
|
||||
let kcAdminClient: KeycloakAdminClient;
|
||||
let currentClientId: string;
|
||||
|
||||
before(async () => {
|
||||
kcAdminClient = new KeycloakAdminClient();
|
||||
await kcAdminClient.auth(credentials);
|
||||
|
||||
// Create a client for testing using v2 API
|
||||
currentClientId = faker.internet.username();
|
||||
await kcAdminClient.clients.v2().post({
|
||||
clientId: currentClientId,
|
||||
protocol: "openid-connect",
|
||||
enabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
// Delete the test client
|
||||
if (currentClientId) {
|
||||
await kcAdminClient.clients.v2().byId(currentClientId).delete();
|
||||
}
|
||||
});
|
||||
|
||||
it("should list clients", async () => {
|
||||
const clients = await kcAdminClient.clients.v2().get();
|
||||
|
||||
expect(clients).to.be.ok;
|
||||
expect(clients).to.be.an("array");
|
||||
expect(clients!.length).to.be.greaterThan(0);
|
||||
|
||||
// Verify our test client is in the list
|
||||
const testClient = clients!.find(
|
||||
(c) => (c as OIDCClientRepresentation).clientId === currentClientId,
|
||||
);
|
||||
expect(testClient).to.be.ok;
|
||||
});
|
||||
|
||||
it("should get a single client by clientId", async () => {
|
||||
const client = await kcAdminClient.clients.v2().byId(currentClientId).get();
|
||||
|
||||
expect(client).to.be.ok;
|
||||
expect((client as OIDCClientRepresentation).clientId).to.equal(
|
||||
currentClientId,
|
||||
);
|
||||
});
|
||||
|
||||
it("should update a client with PUT", async () => {
|
||||
const updatedDescription = "Updated via V2 API test";
|
||||
|
||||
await kcAdminClient.clients.v2().byId(currentClientId).put({
|
||||
clientId: currentClientId,
|
||||
protocol: "openid-connect",
|
||||
description: updatedDescription,
|
||||
});
|
||||
|
||||
const client = await kcAdminClient.clients.v2().byId(currentClientId).get();
|
||||
|
||||
expect((client as OIDCClientRepresentation).description).to.equal(
|
||||
updatedDescription,
|
||||
);
|
||||
});
|
||||
|
||||
it("should patch a client", async () => {
|
||||
const patchedDisplayName = "Patched Display Name";
|
||||
|
||||
// Note: Kiota's patch expects an ArrayBuffer for merge-patch+json
|
||||
const patchBody = JSON.stringify({ displayName: patchedDisplayName });
|
||||
const encoder = new TextEncoder();
|
||||
const patchBuffer = encoder.encode(patchBody).buffer;
|
||||
|
||||
const patchedClient = await kcAdminClient.clients
|
||||
.v2()
|
||||
.byId(currentClientId)
|
||||
.patch(patchBuffer);
|
||||
|
||||
expect((patchedClient as OIDCClientRepresentation).displayName).to.equal(
|
||||
patchedDisplayName,
|
||||
);
|
||||
|
||||
// Verify the change persisted
|
||||
const client = await kcAdminClient.clients.v2().byId(currentClientId).get();
|
||||
|
||||
expect((client as OIDCClientRepresentation).displayName).to.equal(
|
||||
patchedDisplayName,
|
||||
);
|
||||
});
|
||||
|
||||
it("should create and delete a client", async () => {
|
||||
const clientId = faker.internet.username();
|
||||
|
||||
// Create a new client using v2 API
|
||||
await kcAdminClient.clients.v2().post({
|
||||
clientId,
|
||||
protocol: "openid-connect",
|
||||
enabled: true,
|
||||
description: "Test client for deletion",
|
||||
});
|
||||
|
||||
// Verify we can get it via v2 API
|
||||
const client = await kcAdminClient.clients.v2().byId(clientId).get();
|
||||
expect((client as OIDCClientRepresentation).clientId).to.equal(clientId);
|
||||
|
||||
// Delete the client using v2 API
|
||||
await kcAdminClient.clients.v2().byId(clientId).delete();
|
||||
|
||||
// Verify it's deleted by checking it's no longer in the list
|
||||
const clients = await kcAdminClient.clients.v2().get();
|
||||
|
||||
const deletedClient = clients!.find(
|
||||
(c) => (c as OIDCClientRepresentation).clientId === clientId,
|
||||
);
|
||||
expect(deletedClient).to.be.undefined;
|
||||
});
|
||||
|
||||
it("should create an OIDC client with full configuration", async () => {
|
||||
const clientId = `full-config-${faker.internet.username()}`;
|
||||
|
||||
await kcAdminClient.clients.v2().post({
|
||||
clientId,
|
||||
protocol: "openid-connect",
|
||||
enabled: true,
|
||||
displayName: "Full Config Test Client",
|
||||
description: "A client with full OIDC configuration",
|
||||
redirectUris: ["http://localhost:3000/callback"],
|
||||
webOrigins: ["http://localhost:3000"],
|
||||
});
|
||||
|
||||
// Get via v2 API and verify
|
||||
const client = await kcAdminClient.clients.v2().byId(clientId).get();
|
||||
|
||||
expect(client).to.be.ok;
|
||||
expect((client as OIDCClientRepresentation).displayName).to.equal(
|
||||
"Full Config Test Client",
|
||||
);
|
||||
expect((client as OIDCClientRepresentation).protocol).to.equal(
|
||||
"openid-connect",
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
await kcAdminClient.clients.v2().byId(clientId).delete();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"extends": "./tsconfig",
|
||||
"include": ["test"]
|
||||
"include": ["src", "test"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ importers:
|
|||
version: 18.3.7(@types/react@18.3.23)
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
cross-env:
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0
|
||||
|
|
@ -137,13 +137,13 @@ importers:
|
|||
version: 1.30.2
|
||||
vite:
|
||||
specifier: ^7.3.0
|
||||
version: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
version: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-plugin-checker:
|
||||
specifier: ^0.12.0
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-dts:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(@types/node@25.0.3)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.5.4(@types/node@25.0.8)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
|
||||
apps/admin-ui:
|
||||
dependencies:
|
||||
|
|
@ -258,7 +258,7 @@ importers:
|
|||
version: 18.3.7(@types/react@18.3.23)
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
cross-env:
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0
|
||||
|
|
@ -273,22 +273,22 @@ importers:
|
|||
version: 3.6.3
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@swc/core@1.15.8)(@types/node@25.0.3)(typescript@5.9.3)
|
||||
version: 10.9.2(@swc/core@1.15.8)(@types/node@25.0.8)(typescript@5.9.3)
|
||||
uuid:
|
||||
specifier: ^13.0.0
|
||||
version: 13.0.0
|
||||
vite:
|
||||
specifier: ^7.3.0
|
||||
version: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
version: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-plugin-checker:
|
||||
specifier: ^0.12.0
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-dts:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(@types/node@25.0.3)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.5.4(@types/node@25.0.8)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vitest:
|
||||
specifier: ^4.0.16
|
||||
version: 4.0.16(@types/node@25.0.3)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
version: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.8)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
apps/create-keycloak-theme:
|
||||
dependencies:
|
||||
|
|
@ -328,6 +328,24 @@ importers:
|
|||
|
||||
libs/keycloak-admin-client:
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions':
|
||||
specifier: ^1.0.0-preview.86
|
||||
version: 1.0.0-preview.99
|
||||
'@microsoft/kiota-http-fetchlibrary':
|
||||
specifier: ^1.0.0-preview.80
|
||||
version: 1.0.0-preview.99
|
||||
'@microsoft/kiota-serialization-form':
|
||||
specifier: ^1.0.0-preview.74
|
||||
version: 1.0.0-preview.99
|
||||
'@microsoft/kiota-serialization-json':
|
||||
specifier: ^1.0.0-preview.86
|
||||
version: 1.0.0-preview.99
|
||||
'@microsoft/kiota-serialization-multipart':
|
||||
specifier: ^1.0.0-preview.67
|
||||
version: 1.0.0-preview.99
|
||||
'@microsoft/kiota-serialization-text':
|
||||
specifier: ^1.0.0-preview.79
|
||||
version: 1.0.0-preview.99
|
||||
camelize-ts:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
|
|
@ -338,6 +356,9 @@ importers:
|
|||
'@faker-js/faker':
|
||||
specifier: ^10.2.0
|
||||
version: 10.2.0
|
||||
'@microsoft/kiota':
|
||||
specifier: ^1.29.0
|
||||
version: 1.29.0
|
||||
'@types/chai':
|
||||
specifier: ^5.2.2
|
||||
version: 5.2.2
|
||||
|
|
@ -362,6 +383,9 @@ importers:
|
|||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@swc/core@1.15.8)(@types/node@25.0.3)(typescript@5.9.3)
|
||||
tsx:
|
||||
specifier: ^4.19.2
|
||||
version: 4.21.0
|
||||
|
||||
libs/ui-shared:
|
||||
dependencies:
|
||||
|
|
@ -413,25 +437,25 @@ importers:
|
|||
version: 18.3.7(@types/react@18.3.23)
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
rollup-plugin-peer-deps-external:
|
||||
specifier: ^2.2.4
|
||||
version: 2.2.4(rollup@4.55.1)
|
||||
vite:
|
||||
specifier: ^7.3.0
|
||||
version: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
version: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-plugin-checker:
|
||||
specifier: ^0.12.0
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-dts:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(@types/node@25.0.3)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 4.5.4(@types/node@25.0.8)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vite-plugin-lib-inject-css:
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
version: 2.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
vitest:
|
||||
specifier: ^4.0.16
|
||||
version: 4.0.16(@types/node@25.0.3)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
version: 4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.8)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
themes-vendor:
|
||||
dependencies:
|
||||
|
|
@ -1046,6 +1070,27 @@ packages:
|
|||
resolution: {integrity: sha512-LhKytJM5ZJkbHQVfW/3o747rZUNs/MGg6j/wt/9qwwqEOfvUDTYXXxIBuMgrRXhJ528p41iyz4zjBVHZU74Odg==}
|
||||
hasBin: true
|
||||
|
||||
'@microsoft/kiota-abstractions@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-6qrlwGCO3DbvpA7tszqk7JNQPFPDg8gv5NGMTziwdtHqaQrUALKusm3vdJGPVGrbNiZL6/lBaY5NSUvLtlhRCg==}
|
||||
|
||||
'@microsoft/kiota-http-fetchlibrary@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-lIruiYf8L7DPG0Fm92QN5YK4zx4sh76EtTONUAqBCxt5AtEJ7KQceBajaXQsjfcndUAp9LmDVdqR44o8sc9/mA==}
|
||||
|
||||
'@microsoft/kiota-serialization-form@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-BdXxqNfy+5yWTyxpBguqJYy6E9RRotrDClRcUO89okFcR5N6s6xenjsvGw++q9KWNi7qcHrqaG8xlRz1TLk81Q==}
|
||||
|
||||
'@microsoft/kiota-serialization-json@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-kDmMYmB7XkRprlLviEynRPDkE45JDxqiuUopfBRMvNK4qhzFiJTXGLihZ2FG6fdVu9LbV3/W0QxbeGP35kDK6A==}
|
||||
|
||||
'@microsoft/kiota-serialization-multipart@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-cfviCAVTlZPD+MUgdTIgsX/IfHND+gKQhem3vJeo7l5Qqz2rvvVFXOHwECI19umO9Un1QFKe1V5wg+M+aj90+g==}
|
||||
|
||||
'@microsoft/kiota-serialization-text@1.0.0-preview.99':
|
||||
resolution: {integrity: sha512-gcBffQRI1soHVAiS4YjfMr3SQ9fC8xVUGMfarTTszU4PjpxyFOknaWoFdt/0rvMeavI9jOtbyvDKAf77cZyYIQ==}
|
||||
|
||||
'@microsoft/kiota@1.29.0':
|
||||
resolution: {integrity: sha512-qqIlTz48OJ5ZMRoTA/uQA70B7ltS4lPSs9atG5PUn+dKZcgXny3LzQPe12B1LsKoBJYbwhaU3fD8/C1DsLW6Cw==}
|
||||
|
||||
'@microsoft/tsdoc-config@0.17.1':
|
||||
resolution: {integrity: sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==}
|
||||
|
||||
|
|
@ -1120,6 +1165,10 @@ packages:
|
|||
'@octokit/types@16.0.0':
|
||||
resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==}
|
||||
|
||||
'@opentelemetry/api@1.9.0':
|
||||
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@patternfly/patternfly@4.224.5':
|
||||
resolution: {integrity: sha512-io0huj+LCP5FgDZJDaLv1snxktTYs8iCFz/W1VDRneYoebNHLmGfQdF7Yn8bS6PF7qmN6oJKEBlq3AjmmE8vdA==}
|
||||
|
||||
|
|
@ -1410,6 +1459,9 @@ packages:
|
|||
'@standard-schema/spec@1.1.0':
|
||||
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
|
||||
|
||||
'@std-uritemplate/std-uritemplate@2.0.8':
|
||||
resolution: {integrity: sha512-8oj7jKksoTRxjdPkWKX9FyOKDS8ORBm+ZfTSHm0f3eYha8cI0O1d57gyduOIAX7Y2uUukNDNlxlvGb+FFkE7yQ==}
|
||||
|
||||
'@swc/core-darwin-arm64@1.15.8':
|
||||
resolution: {integrity: sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -1673,6 +1725,9 @@ packages:
|
|||
'@types/node@25.0.3':
|
||||
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==}
|
||||
|
||||
'@types/node@25.0.8':
|
||||
resolution: {integrity: sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg==}
|
||||
|
||||
'@types/prismjs@1.26.5':
|
||||
resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==}
|
||||
|
||||
|
|
@ -1849,6 +1904,10 @@ packages:
|
|||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
adm-zip@0.5.16:
|
||||
resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==}
|
||||
engines: {node: '>=12.0'}
|
||||
|
||||
agent-base@7.1.4:
|
||||
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||
engines: {node: '>= 14'}
|
||||
|
|
@ -2672,6 +2731,9 @@ packages:
|
|||
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-tsconfig@4.13.0:
|
||||
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
|
@ -3363,6 +3425,9 @@ packages:
|
|||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
original-fs@1.2.0:
|
||||
resolution: {integrity: sha512-IGo+qFumpIV65oDchJrqL0BOk9kr82fObnTesNJt8t3YgP6vfqcmRs0ofPzg3D9PKMeBHt7lrg1k/6L+oFdS8g==}
|
||||
|
||||
own-keys@1.0.1:
|
||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -3644,6 +3709,9 @@ packages:
|
|||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
resolve@1.22.10:
|
||||
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -3924,6 +3992,9 @@ packages:
|
|||
tinybench@2.9.0:
|
||||
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||
|
||||
tinyduration@3.4.1:
|
||||
resolution: {integrity: sha512-NemFoamVYn7TmtwZKZ3OiliM9fZkr6EWiTM+wKknco6POSy2gS689xx/pXip0JYp40HXpUw6k65CUYHWYUXdaA==}
|
||||
|
||||
tinyexec@1.0.2:
|
||||
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
|
||||
engines: {node: '>=18'}
|
||||
|
|
@ -3984,6 +4055,11 @@ packages:
|
|||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tsx@4.21.0:
|
||||
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
|
@ -4238,6 +4314,10 @@ packages:
|
|||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
vscode-jsonrpc@8.2.1:
|
||||
resolution: {integrity: sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
vscode-uri@3.1.0:
|
||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||
|
||||
|
|
@ -5027,23 +5107,23 @@ snapshots:
|
|||
|
||||
'@kwsites/promise-deferred@1.1.1': {}
|
||||
|
||||
'@microsoft/api-extractor-model@7.30.7(@types/node@25.0.3)':
|
||||
'@microsoft/api-extractor-model@7.30.7(@types/node@25.0.8)':
|
||||
dependencies:
|
||||
'@microsoft/tsdoc': 0.15.1
|
||||
'@microsoft/tsdoc-config': 0.17.1
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.3)
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.8)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@microsoft/api-extractor@7.52.10(@types/node@25.0.3)':
|
||||
'@microsoft/api-extractor@7.52.10(@types/node@25.0.8)':
|
||||
dependencies:
|
||||
'@microsoft/api-extractor-model': 7.30.7(@types/node@25.0.3)
|
||||
'@microsoft/api-extractor-model': 7.30.7(@types/node@25.0.8)
|
||||
'@microsoft/tsdoc': 0.15.1
|
||||
'@microsoft/tsdoc-config': 0.17.1
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.3)
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.8)
|
||||
'@rushstack/rig-package': 0.5.3
|
||||
'@rushstack/terminal': 0.15.4(@types/node@25.0.3)
|
||||
'@rushstack/ts-command-line': 5.0.2(@types/node@25.0.3)
|
||||
'@rushstack/terminal': 0.15.4(@types/node@25.0.8)
|
||||
'@rushstack/ts-command-line': 5.0.2(@types/node@25.0.8)
|
||||
lodash: 4.17.21
|
||||
minimatch: 10.0.3
|
||||
resolve: 1.22.10
|
||||
|
|
@ -5053,6 +5133,46 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@microsoft/kiota-abstractions@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@std-uritemplate/std-uritemplate': 2.0.8
|
||||
tinyduration: 3.4.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota-http-fetchlibrary@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions': 1.0.0-preview.99
|
||||
'@opentelemetry/api': 1.9.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota-serialization-form@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions': 1.0.0-preview.99
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota-serialization-json@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions': 1.0.0-preview.99
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota-serialization-multipart@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions': 1.0.0-preview.99
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota-serialization-text@1.0.0-preview.99':
|
||||
dependencies:
|
||||
'@microsoft/kiota-abstractions': 1.0.0-preview.99
|
||||
tslib: 2.8.1
|
||||
|
||||
'@microsoft/kiota@1.29.0':
|
||||
dependencies:
|
||||
adm-zip: 0.5.16
|
||||
original-fs: 1.2.0
|
||||
uuid: 13.0.0
|
||||
vscode-jsonrpc: 8.2.1
|
||||
|
||||
'@microsoft/tsdoc-config@0.17.1':
|
||||
dependencies:
|
||||
'@microsoft/tsdoc': 0.15.1
|
||||
|
|
@ -5138,6 +5258,8 @@ snapshots:
|
|||
dependencies:
|
||||
'@octokit/openapi-types': 27.0.0
|
||||
|
||||
'@opentelemetry/api@1.9.0': {}
|
||||
|
||||
'@patternfly/patternfly@4.224.5': {}
|
||||
|
||||
'@patternfly/patternfly@5.4.2': {}
|
||||
|
|
@ -5392,7 +5514,7 @@ snapshots:
|
|||
'@rollup/rollup-win32-x64-msvc@4.55.1':
|
||||
optional: true
|
||||
|
||||
'@rushstack/node-core-library@5.14.0(@types/node@25.0.3)':
|
||||
'@rushstack/node-core-library@5.14.0(@types/node@25.0.8)':
|
||||
dependencies:
|
||||
ajv: 8.13.0
|
||||
ajv-draft-04: 1.0.0(ajv@8.13.0)
|
||||
|
|
@ -5403,23 +5525,23 @@ snapshots:
|
|||
resolve: 1.22.10
|
||||
semver: 7.5.4
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.8
|
||||
|
||||
'@rushstack/rig-package@0.5.3':
|
||||
dependencies:
|
||||
resolve: 1.22.10
|
||||
strip-json-comments: 3.1.1
|
||||
|
||||
'@rushstack/terminal@0.15.4(@types/node@25.0.3)':
|
||||
'@rushstack/terminal@0.15.4(@types/node@25.0.8)':
|
||||
dependencies:
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.3)
|
||||
'@rushstack/node-core-library': 5.14.0(@types/node@25.0.8)
|
||||
supports-color: 8.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.8
|
||||
|
||||
'@rushstack/ts-command-line@5.0.2(@types/node@25.0.3)':
|
||||
'@rushstack/ts-command-line@5.0.2(@types/node@25.0.8)':
|
||||
dependencies:
|
||||
'@rushstack/terminal': 0.15.4(@types/node@25.0.3)
|
||||
'@rushstack/terminal': 0.15.4(@types/node@25.0.8)
|
||||
'@types/argparse': 1.0.38
|
||||
argparse: 1.0.10
|
||||
string-argv: 0.3.2
|
||||
|
|
@ -5428,6 +5550,8 @@ snapshots:
|
|||
|
||||
'@standard-schema/spec@1.1.0': {}
|
||||
|
||||
'@std-uritemplate/std-uritemplate@2.0.8': {}
|
||||
|
||||
'@swc/core-darwin-arm64@1.15.8':
|
||||
optional: true
|
||||
|
||||
|
|
@ -5696,6 +5820,10 @@ snapshots:
|
|||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
'@types/node@25.0.8':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
'@types/prismjs@1.26.5': {}
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
|
|
@ -5718,7 +5846,7 @@ snapshots:
|
|||
|
||||
'@types/tar-stream@3.1.4':
|
||||
dependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.8
|
||||
|
||||
'@types/unist@2.0.11': {}
|
||||
|
||||
|
|
@ -5827,11 +5955,11 @@ snapshots:
|
|||
|
||||
'@ungap/structured-clone@1.3.0': {}
|
||||
|
||||
'@vitejs/plugin-react-swc@4.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))':
|
||||
'@vitejs/plugin-react-swc@4.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.47
|
||||
'@swc/core': 1.15.8
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
|
||||
|
|
@ -5844,13 +5972,13 @@ snapshots:
|
|||
chai: 6.2.2
|
||||
tinyrainbow: 3.0.3
|
||||
|
||||
'@vitest/mocker@4.0.16(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))':
|
||||
'@vitest/mocker@4.0.16(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@vitest/spy': 4.0.16
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.21
|
||||
optionalDependencies:
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
'@vitest/pretty-format@4.0.16':
|
||||
dependencies:
|
||||
|
|
@ -5929,6 +6057,8 @@ snapshots:
|
|||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
adm-zip@0.5.16: {}
|
||||
|
||||
agent-base@7.1.4: {}
|
||||
|
||||
ajv-draft-04@1.0.0(ajv@8.13.0):
|
||||
|
|
@ -6850,6 +6980,10 @@ snapshots:
|
|||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
get-tsconfig@4.13.0:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
glob-parent@5.1.2:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
|
|
@ -7596,6 +7730,8 @@ snapshots:
|
|||
type-check: 0.4.0
|
||||
word-wrap: 1.2.5
|
||||
|
||||
original-fs@1.2.0: {}
|
||||
|
||||
own-keys@1.0.1:
|
||||
dependencies:
|
||||
get-intrinsic: 1.3.0
|
||||
|
|
@ -7911,6 +8047,8 @@ snapshots:
|
|||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
resolve@1.22.10:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
|
|
@ -8281,6 +8419,8 @@ snapshots:
|
|||
|
||||
tinybench@2.9.0: {}
|
||||
|
||||
tinyduration@3.4.1: {}
|
||||
|
||||
tinyexec@1.0.2: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
|
|
@ -8336,8 +8476,35 @@ snapshots:
|
|||
optionalDependencies:
|
||||
'@swc/core': 1.15.8
|
||||
|
||||
ts-node@10.9.2(@swc/core@1.15.8)(@types/node@25.0.8)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 25.0.8
|
||||
acorn: 8.15.0
|
||||
acorn-walk: 8.3.4
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
typescript: 5.9.3
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.15.8
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tsx@4.21.0:
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
get-tsconfig: 4.13.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
type-check@0.4.0:
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
|
@ -8490,7 +8657,7 @@ snapshots:
|
|||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.3
|
||||
|
||||
vite-plugin-checker@0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)):
|
||||
vite-plugin-checker@0.12.0(eslint@9.39.2)(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
chokidar: 4.0.3
|
||||
|
|
@ -8499,16 +8666,16 @@ snapshots:
|
|||
picomatch: 4.0.3
|
||||
tiny-invariant: 1.3.3
|
||||
tinyglobby: 0.2.15
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vscode-uri: 3.1.0
|
||||
optionalDependencies:
|
||||
eslint: 9.39.2
|
||||
optionator: 0.9.4
|
||||
typescript: 5.9.3
|
||||
|
||||
vite-plugin-dts@4.5.4(@types/node@25.0.3)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)):
|
||||
vite-plugin-dts@4.5.4(@types/node@25.0.8)(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@microsoft/api-extractor': 7.52.10(@types/node@25.0.3)
|
||||
'@microsoft/api-extractor': 7.52.10(@types/node@25.0.8)
|
||||
'@rollup/pluginutils': 5.2.0(rollup@4.55.1)
|
||||
'@volar/typescript': 2.4.22
|
||||
'@vue/language-core': 2.2.0(typescript@5.9.3)
|
||||
|
|
@ -8519,20 +8686,20 @@ snapshots:
|
|||
magic-string: 0.30.17
|
||||
typescript: 5.9.3
|
||||
optionalDependencies:
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
vite-plugin-lib-inject-css@2.2.2(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)):
|
||||
vite-plugin-lib-inject-css@2.2.2(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@ast-grep/napi': 0.36.3
|
||||
magic-string: 0.30.17
|
||||
picocolors: 1.1.1
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2):
|
||||
vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
fdir: 6.5.0(picomatch@4.0.3)
|
||||
|
|
@ -8541,16 +8708,17 @@ snapshots:
|
|||
rollup: 4.55.1
|
||||
tinyglobby: 0.2.15
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@types/node': 25.0.8
|
||||
fsevents: 2.3.3
|
||||
lightningcss: 1.30.2
|
||||
terser: 5.43.1
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.2
|
||||
|
||||
vitest@4.0.16(@types/node@25.0.3)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2):
|
||||
vitest@4.0.16(@opentelemetry/api@1.9.0)(@types/node@25.0.8)(jsdom@27.4.0)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.0.16
|
||||
'@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2))
|
||||
'@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@vitest/pretty-format': 4.0.16
|
||||
'@vitest/runner': 4.0.16
|
||||
'@vitest/snapshot': 4.0.16
|
||||
|
|
@ -8567,10 +8735,11 @@ snapshots:
|
|||
tinyexec: 1.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tinyrainbow: 3.0.3
|
||||
vite: 7.3.0(@types/node@25.0.3)(lightningcss@1.30.2)(terser@5.43.1)(yaml@2.8.2)
|
||||
vite: 7.3.0(@types/node@25.0.8)(lightningcss@1.30.2)(terser@5.43.1)(tsx@4.21.0)(yaml@2.8.2)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 25.0.3
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@types/node': 25.0.8
|
||||
jsdom: 27.4.0
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
|
|
@ -8587,6 +8756,8 @@ snapshots:
|
|||
|
||||
void-elements@3.1.0: {}
|
||||
|
||||
vscode-jsonrpc@8.2.1: {}
|
||||
|
||||
vscode-uri@3.1.0: {}
|
||||
|
||||
w3c-xmlserializer@5.0.0:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.keycloak.quarkus.runtime.oas;
|
|||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
|
@ -58,6 +59,9 @@ public class OASModelFilter implements OASFilter {
|
|||
newPaths.forEach(paths::addPathItem);
|
||||
openAPI.setPaths(paths);
|
||||
|
||||
// Remove dangling allOf references (references to schemas that don't exist, e.g. hidden schemas)
|
||||
removeDanglingAllOfReferences(openAPI);
|
||||
|
||||
Map<String, Set<Schema>> discriminatorPropertiesToBeAdded = new HashMap<>();
|
||||
|
||||
// Reflect Jackson annotations in OpenAPI spec
|
||||
|
|
@ -111,6 +115,42 @@ public class OASModelFilter implements OASFilter {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes allOf references that point to schemas that don't exist in the OpenAPI document.
|
||||
* This can happen when a parent class is marked with @Schema(hidden = true).
|
||||
*/
|
||||
private void removeDanglingAllOfReferences(OpenAPI openAPI) {
|
||||
if (openAPI.getComponents() == null || openAPI.getComponents().getSchemas() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> existingSchemaNames = openAPI.getComponents().getSchemas().keySet();
|
||||
|
||||
openAPI.getComponents().getSchemas().values().forEach(schema -> {
|
||||
if (schema.getAllOf() != null && !schema.getAllOf().isEmpty()) {
|
||||
List<Schema> filteredAllOf = schema.getAllOf().stream()
|
||||
.filter(allOfSchema -> {
|
||||
if (allOfSchema.getRef() != null) {
|
||||
String refName = allOfSchema.getRef().substring(REF_PREFIX.length());
|
||||
boolean isDangling = !existingSchemaNames.contains(refName);
|
||||
if (isDangling) {
|
||||
log.debugf("Removing dangling allOf reference to: %s", refName);
|
||||
}
|
||||
return !isDangling;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (filteredAllOf.isEmpty()) {
|
||||
schema.setAllOf(null);
|
||||
} else if (filteredAllOf.size() != schema.getAllOf().size()) {
|
||||
schema.setAllOf(filteredAllOf);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private PathItem sortOperationsByMethod(PathItem pathItem) {
|
||||
PathItem sortedPathItem = OASFactory.createPathItem();
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
|||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||
@Schema
|
||||
@Schema(hidden = true)
|
||||
public class BaseRepresentation {
|
||||
|
||||
@JsonIgnore
|
||||
|
|
|
|||
Loading…
Reference in a new issue