diff --git a/docs/command-graph.html b/docs/command-graph.html
index f8b76d74..2645c540 100644
--- a/docs/command-graph.html
+++ b/docs/command-graph.html
@@ -269,11 +269,11 @@
// asset-registry
{ id: "ar_list", label: "list", group: "command", path: "asset-registry list",
- description: "List all registered asset types", options: ["-p, --profile ", "--json", "-h, --help"] },
+ description: "List all registered asset types", options: ["-p, --profile ", "--flavor ", "--json", "-h, --help"] },
{ id: "ar_get", label: "get", group: "command", path: "asset-registry get",
description: "Get the descriptor for a specific asset type", options: ["-p, --profile ", "--assetType (e.g., BOARD_V2)", "--json", "-h, --help"] },
{ id: "ar_schema", label: "schema", group: "command", path: "asset-registry schema",
- description: "Get the JSON schema for an asset type's configuration", options: ["-p, --profile ", "--assetType (e.g., BOARD_V2)", "--json", "-h, --help"] },
+ description: "Get the JSON schema for an asset type's configuration", options: ["-p, --profile ", "--assetType (e.g., BOARD_V2)", "--path ", "--json", "-h, --help"] },
{ id: "ar_examples", label: "examples", group: "command", path: "asset-registry examples",
description: "Get example configurations for an asset type", options: ["-p, --profile ", "--assetType (e.g., BOARD_V2)", "--json", "-h, --help"] },
diff --git a/docs/user-guide/asset-registry-commands.md b/docs/user-guide/asset-registry-commands.md
index dec25db0..89f47565 100644
--- a/docs/user-guide/asset-registry-commands.md
+++ b/docs/user-guide/asset-registry-commands.md
@@ -26,6 +26,17 @@ It is also possible to use the `--json` option for writing the full response to
content-cli asset-registry list --json
```
+To list only the asset types that apply to one package flavor, pass `--flavor`:
+
+```
+content-cli asset-registry list --flavor STUDIO
+```
+
+Options:
+
+- `--flavor ` – List only the asset types that apply to this package flavor (`STUDIO`, `CCM` or `OCDM`, case-insensitive). Asset types that do not declare any flavors apply to all of them.
+- `--json` – Write the full response to a JSON file in the working directory
+
## Get Asset Type
Get the full descriptor for a specific asset type, including schema version, service base path, and endpoint paths.
@@ -67,9 +78,19 @@ The response is the full JSON Schema (draft-07) for the asset type. Use `--json`
content-cli asset-registry schema --assetType BOARD_V2 --json
```
+Large schemas can be read one part at a time with `--path`. Write the path the same way the schema writes its `$ref` values. `#` returns the entry point, the top level of the schema without its definitions, and any `$ref` in a response can be passed as the next `--path`:
+
+```
+content-cli asset-registry schema --assetType BOARD_V2 --path '#'
+content-cli asset-registry schema --assetType BOARD_V2 --path '#/$defs/table'
+```
+
+Quote the path so the shell does not interpret `#` or `$`. Asset types that do not support partial schemas return the full schema.
+
Options:
- `--assetType ` (required) – The asset type identifier
+- `--path ` – Return only this part of the schema, written like a `$ref` inside it (for example, `#/$defs/table`)
- `--json` – Write the schema to a JSON file in the working directory
## Validating assets
diff --git a/src/commands/asset-registry/asset-registry-api.ts b/src/commands/asset-registry/asset-registry-api.ts
index 630c1dbb..71126682 100644
--- a/src/commands/asset-registry/asset-registry-api.ts
+++ b/src/commands/asset-registry/asset-registry-api.ts
@@ -15,9 +15,9 @@ export class AssetRegistryApi {
this.httpClient = () => context.httpClient;
}
- public async listTypes(): Promise {
+ public async listTypes(flavor?: string): Promise {
return this.httpClient()
- .get(AssetRegistryApi.endpointUrl("types"))
+ .get(AssetRegistryApi.withQuery(AssetRegistryApi.endpointUrl("types"), { flavor }))
.catch((e) => handleAssetRegistryApiError("listing asset registry types", e));
}
@@ -27,9 +27,9 @@ export class AssetRegistryApi {
.catch((e) => handleAssetRegistryApiError(`getting asset type '${assetType}'`, e));
}
- public async getSchema(assetType: string): Promise {
+ public async getSchema(assetType: string, path?: string): Promise {
return this.httpClient()
- .get(AssetRegistryApi.endpointUrl("schemas", encodeURIComponent(assetType)))
+ .get(AssetRegistryApi.withQuery(AssetRegistryApi.endpointUrl("schemas", encodeURIComponent(assetType)), { path }))
.catch((e) => handleAssetRegistryApiError(`getting schema for asset type '${assetType}'`, e));
}
@@ -42,4 +42,13 @@ export class AssetRegistryApi {
private static endpointUrl(...segments: string[]): string {
return `${AssetRegistryApi.BASE_URL}/${segments.join("/")}`;
}
+
+ private static withQuery(url: string, params: Record): string {
+ const queryParams = new URLSearchParams();
+ Object.entries(params)
+ .filter(([, value]) => value !== undefined && value.trim() !== "")
+ .forEach(([name, value]) => queryParams.set(name, value));
+ const query = queryParams.toString();
+ return query ? `${url}?${query}` : url;
+ }
}
diff --git a/src/commands/asset-registry/asset-registry.service.ts b/src/commands/asset-registry/asset-registry.service.ts
index 7f69fa6f..e2ae3c0d 100644
--- a/src/commands/asset-registry/asset-registry.service.ts
+++ b/src/commands/asset-registry/asset-registry.service.ts
@@ -15,8 +15,8 @@ export class AssetRegistryService {
this.cuiFileService = new CuiFileService(context);
}
- public async listTypes(jsonResponse: boolean): Promise {
- const metadata = await this.api.listTypes();
+ public async listTypes(jsonResponse: boolean, flavor?: string): Promise {
+ const metadata = await this.api.listTypes(flavor);
const descriptors = Object.values(metadata.types);
if (jsonResponse) {
@@ -46,8 +46,8 @@ export class AssetRegistryService {
}
}
- public async getSchema(assetType: string, jsonResponse: boolean): Promise {
- const data = await this.api.getSchema(assetType);
+ public async getSchema(assetType: string, jsonResponse: boolean, path?: string): Promise {
+ const data = await this.api.getSchema(assetType, path);
await this.outputResponse(data, jsonResponse);
}
diff --git a/src/commands/asset-registry/module.ts b/src/commands/asset-registry/module.ts
index 20f8afdf..5d989979 100644
--- a/src/commands/asset-registry/module.ts
+++ b/src/commands/asset-registry/module.ts
@@ -11,6 +11,7 @@ class Module extends IModule {
assetRegistryCommand.command("list")
.description("List all registered asset types")
+ .option("--flavor ", "Lists only the asset types that apply to the given package flavor (e.g., STUDIO)")
.option("--json", "Return the response as a JSON file")
.action(this.listTypes);
@@ -23,6 +24,7 @@ class Module extends IModule {
assetRegistryCommand.command("schema")
.description("Get the JSON schema for an asset type's configuration")
.requiredOption("--assetType ", "The asset type identifier (e.g., BOARD_V2)")
+ .option("--path ", "Return only this part of the schema, written like a $ref inside it (e.g., '#/$defs/table'); '#' returns the entry point")
.option("--json", "Return the response as a JSON file")
.action(this.getSchema);
@@ -34,7 +36,7 @@ class Module extends IModule {
}
private async listTypes(context: Context, command: Command, options: OptionValues): Promise {
- await new AssetRegistryService(context).listTypes(!!options.json);
+ await new AssetRegistryService(context).listTypes(!!options.json, options.flavor);
}
private async getType(context: Context, command: Command, options: OptionValues): Promise {
@@ -42,7 +44,7 @@ class Module extends IModule {
}
private async getSchema(context: Context, command: Command, options: OptionValues): Promise {
- await new AssetRegistryService(context).getSchema(options.assetType, !!options.json);
+ await new AssetRegistryService(context).getSchema(options.assetType, !!options.json, options.path);
}
private async getExamples(context: Context, command: Command, options: OptionValues): Promise {
diff --git a/tests/commands/asset-registry/asset-registry-list.spec.ts b/tests/commands/asset-registry/asset-registry-list.spec.ts
index 5d5e28dd..da22696e 100644
--- a/tests/commands/asset-registry/asset-registry-list.spec.ts
+++ b/tests/commands/asset-registry/asset-registry-list.spec.ts
@@ -90,6 +90,20 @@ describe("Asset registry list", () => {
expect(written.types["SEMANTIC_MODEL"].assetType).toBe("SEMANTIC_MODEL");
});
+ it("Should list only the asset types of the given flavor", async () => {
+ const studioOnly: AssetRegistryMetadata = {
+ types: {
+ BOARD_V2: metadata.types.BOARD_V2,
+ },
+ };
+ mockAxiosGet("https://myTeam.celonis.cloud/pacman/api/core/asset-registry/types?flavor=STUDIO", studioOnly);
+
+ await new AssetRegistryService(testContext).listTypes(false, "STUDIO");
+
+ expect(loggingTestTransport.logMessages).toHaveLength(1);
+ expect(loggingTestTransport.logMessages[0].message).toContain("BOARD_V2 - View [DASHBOARDS]");
+ });
+
it("Should handle empty registry", async () => {
mockAxiosGet("https://myTeam.celonis.cloud/pacman/api/core/asset-registry/types", { types: {} });
diff --git a/tests/commands/asset-registry/asset-registry-schema.spec.ts b/tests/commands/asset-registry/asset-registry-schema.spec.ts
index 6e65d80d..483cf708 100644
--- a/tests/commands/asset-registry/asset-registry-schema.spec.ts
+++ b/tests/commands/asset-registry/asset-registry-schema.spec.ts
@@ -36,4 +36,25 @@ describe("Asset registry schema", () => {
expect(written.$schema).toBe("http://json-schema.org/draft-07/schema#");
expect(written.title).toBe("Board");
});
+
+ it("Should request only the given part of the schema when a path is passed", async () => {
+ const fragment = { type: "object", properties: { columns: { $ref: "#/$defs/column" } } };
+ mockAxiosGet(
+ "https://myTeam.celonis.cloud/pacman/api/core/asset-registry/schemas/BOARD_V2?path=%23%2F%24defs%2Ftable",
+ fragment
+ );
+
+ await new AssetRegistryService(testContext).getSchema("BOARD_V2", false, "#/$defs/table");
+
+ expect(loggingTestTransport.logMessages).toHaveLength(1);
+ expect(loggingTestTransport.logMessages[0].message).toContain("#/$defs/column");
+ });
+
+ it("Should request the full schema when the path is blank", async () => {
+ mockAxiosGet("https://myTeam.celonis.cloud/pacman/api/core/asset-registry/schemas/BOARD_V2", schemaResponse);
+
+ await new AssetRegistryService(testContext).getSchema("BOARD_V2", false, " ");
+
+ expect(loggingTestTransport.logMessages[0].message).toContain("Board");
+ });
});
diff --git a/tests/integration/commands/asset-registry.spec.ts b/tests/integration/commands/asset-registry.spec.ts
index 5a0d85bf..3b43a17b 100644
--- a/tests/integration/commands/asset-registry.spec.ts
+++ b/tests/integration/commands/asset-registry.spec.ts
@@ -29,12 +29,19 @@ describe("asset-registry command integration", () => {
const result = await runCli(["asset-registry", "schema", "--assetType", "BOARD_V2", "--json"]);
expect(result.exitCode).toBe(0);
- expect(mockService.getSchema).toHaveBeenCalledWith("BOARD_V2", true);
+ expect(mockService.getSchema).toHaveBeenCalledWith("BOARD_V2", true, undefined);
});
it("defaults --json to false when omitted", async () => {
await runCli(["asset-registry", "schema", "--assetType", "BOARD_V2"]);
- expect(mockService.getSchema).toHaveBeenCalledWith("BOARD_V2", false);
+ expect(mockService.getSchema).toHaveBeenCalledWith("BOARD_V2", false, undefined);
+ });
+
+ it("passes --path to getSchema", async () => {
+ const result = await runCli(["asset-registry", "schema", "--assetType", "BOARD_V2", "--path", "#/$defs/table"]);
+
+ expect(result.exitCode).toBe(0);
+ expect(mockService.getSchema).toHaveBeenCalledWith("BOARD_V2", false, "#/$defs/table");
});
});
@@ -70,12 +77,19 @@ describe("asset-registry command integration", () => {
const result = await runCli(["asset-registry", "list", "--json"]);
expect(result.exitCode).toBe(0);
- expect(mockService.listTypes).toHaveBeenCalledWith(true);
+ expect(mockService.listTypes).toHaveBeenCalledWith(true, undefined);
});
it("calls listTypes without --json", async () => {
await runCli(["asset-registry", "list"]);
- expect(mockService.listTypes).toHaveBeenCalledWith(false);
+ expect(mockService.listTypes).toHaveBeenCalledWith(false, undefined);
+ });
+
+ it("passes --flavor to listTypes", async () => {
+ const result = await runCli(["asset-registry", "list", "--flavor", "STUDIO"]);
+
+ expect(result.exitCode).toBe(0);
+ expect(mockService.listTypes).toHaveBeenCalledWith(false, "STUDIO");
});
});