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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions docs/user-guide/sdk-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,7 @@ Published apps block inline scripts, and so does the Local preview by default. S
Print a fresh token that only grants read access to the Celonis SDK, e.g. to authenticate against the npm registry.

```
content-cli -q sdk token
```

The token is printed to the console without any other output when the `-q` option is set, so it can be used in scripts, e.g. to configure npm:

```
npm config set //<team>.celonis.cloud/pro-code-app-manager/api/npm/:_authToken "$(content-cli -q sdk token)"
content-cli sdk token
```

The command requires a device code or client credentials profile. API keys can be used directly for authentication instead.
4 changes: 2 additions & 2 deletions src/content-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ async function run(): Promise<void> {
const globalOpts = bootstrapProgram.opts();

if (!globalOpts.quietmode) {
console.log(`Content CLI - (C) Copyright 2025 - Celonis SE - Version ${VersionUtils.getCurrentCliVersion()}`);
console.log();
console.error(`Content CLI - (C) Copyright 2025 - Celonis SE - Version ${VersionUtils.getCurrentCliVersion()}`);
console.error();
Comment thread
ZgjimHaziri marked this conversation as resolved.
Resolved
}

if (globalOpts.debug) {
Expand Down
13 changes: 6 additions & 7 deletions src/core/command/module-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export class CommandConfig {

private printBetaNoticeIfBetaCommand(): void {
if ((this.cmd as any).isBeta) {
logger.info(chalk.yellow("This command is in beta and may change in future releases."));
logger.warn(chalk.yellow("This command is in beta and may change in future releases."));
}
}

Expand All @@ -266,11 +266,10 @@ export class CommandConfig {
return;
}
const providedOptions = this.cmd.optsWithGlobals();
for (const option of this.cmd.options) {
const optionName = option.attributeName();
if ((option as any).isBeta && Object.hasOwn(providedOptions, optionName)) {
logger.info(chalk.yellow(`The option '${option.long}' is in beta and may change in future releases.`));
}
}
this.cmd.options
.filter(option => (option as any).isBeta && Object.hasOwn(providedOptions, option.attributeName()))
.forEach(option =>
logger.warn(chalk.yellow(`The option '${option.long}' is in beta and may change in future releases.`))
);
}
}
1 change: 1 addition & 0 deletions src/core/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const logger: Logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: "info",
stderrLevels: ["error", "warn"],
format: winston.format.combine(
winston.format.colorize(),
),
Expand Down
45 changes: 45 additions & 0 deletions tests/core/command/module-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,48 @@ describe("CommandConfig action error handling", () => {
).toBe(false);
});
});

describe("CommandConfig beta notices", () => {
beforeEach(() => {
loggingTestTransport.logMessages = [];
});

async function runBetaCommand(): Promise<void> {
const program = new Command();
const configurator = new Configurator(program, testContext);

configurator.command("test-command").beta().action(async () => undefined);

program.exitOverride();
await program.parseAsync(["node", "content-cli", "test-command"]);
}

async function runCommandWithBetaOption(): Promise<void> {
const program = new Command();
const configurator = new Configurator(program, testContext);

configurator
.command("test-command")
.betaOption("--preview", "Beta option")
.action(async () => undefined);

program.exitOverride();
await program.parseAsync(["node", "content-cli", "test-command", "--preview"]);
}

function findLogEntry(text: string) {
return loggingTestTransport.logMessages.find(entry => String(entry.message).includes(text));
}

it("warns that a beta command may change, so the notice goes to stderr", async () => {
await runBetaCommand();

expect(findLogEntry("This command is in beta")?.level).toContain("warn");
});

it("warns that a provided beta option may change, so the notice goes to stderr", async () => {
await runCommandWithBetaOption();

expect(findLogEntry("The option '--preview' is in beta")?.level).toContain("warn");
});
});
22 changes: 22 additions & 0 deletions tests/core/utils/logger.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as winston from "winston";
import { logger } from "../../../src/core/utils/logger";

describe("Logger", () => {
function findConsoleTransport(): winston.transports.ConsoleTransportInstance {
return logger.transports.find(
transport => transport instanceof winston.transports.Console
) as winston.transports.ConsoleTransportInstance;
}

it("writes errors and warnings to stderr, so they stay out of captured command output", () => {
const consoleTransport = findConsoleTransport() as any;

expect(consoleTransport.stderrLevels).toEqual({ error: true, warn: true });
});

it("writes info to stdout", () => {
const consoleTransport = findConsoleTransport() as any;

expect(consoleTransport.stderrLevels.info).toBeUndefined();
});
});
Loading