Skip to content
Closed
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
0213926
Add new custom resolver to fetch the reference from private template …
AayushSaini101 Jun 21, 2025
c685ac2
chore: add changeset for PR #1810
Jun 21, 2025
181dbb9
Merge branch 'master' into 1796-b
asyncapi-bot Jul 2, 2025
82ac26b
Merge branch 'master' into 1796-b
asyncapi-bot Aug 4, 2025
0a4c2ed
Merge branch 'master' into 1796-b
asyncapi-bot Aug 11, 2025
26037eb
Merge remote-tracking branch 'remote/master' into 1796-b
Shurtu-gal Aug 19, 2025
6473326
chore: separate cli and api
Shurtu-gal Aug 19, 2025
b18cd33
chore: add changeset for PR #1810
Aug 19, 2025
7e72056
Merge branch 'master' into 1796-b
asyncapi-bot Aug 20, 2025
cccf712
Merge branch 'master' into 1796-b
asyncapi-bot Aug 25, 2025
0572240
Merge branch 'master' into 1796-b
AayushSaini101 Sep 6, 2025
d484f2f
update
AayushSaini101 Sep 7, 2025
ab58365
remove invalid changes
AayushSaini101 Sep 7, 2025
932c09c
update package-lock.json
AayushSaini101 Sep 7, 2025
ec5eb66
update package-lock.json
AayushSaini101 Sep 7, 2025
7e4b523
fix github jobs
AayushSaini101 Sep 7, 2025
c7501a1
Fix elint issue
AayushSaini101 Sep 7, 2025
925b90a
remove uncessary files
AayushSaini101 Sep 7, 2025
5d651f7
remove invalid file
AayushSaini101 Sep 7, 2025
5d76066
update-changeset
AayushSaini101 Sep 7, 2025
5d89ce7
update-doc
AayushSaini101 Sep 7, 2025
3461288
update-suggestions
AayushSaini101 Sep 8, 2025
4f63af9
add new testcase
AayushSaini101 Sep 8, 2025
5d83ac7
add new testcases
AayushSaini101 Sep 8, 2025
22c180a
Merge branch 'master' into 1796-b
asyncapi-bot Sep 9, 2025
7e0a666
chore: add changeset for PR #1810
Sep 9, 2025
ca35a23
Merge branch 'master' into 1796-b
asyncapi-bot Sep 15, 2025
d3989d5
Merge branch 'master' into 1796-b
asyncapi-bot Sep 16, 2025
baadf95
Merge branch 'master' into 1796-b
asyncapi-bot Sep 19, 2025
f1a4d39
add new test case for the validationService
AayushSaini101 Sep 19, 2025
f729636
chore: add changeset for PR #1810
Sep 19, 2025
af11ce4
update test case
AayushSaini101 Sep 19, 2025
824bdb9
update changeset
AayushSaini101 Sep 19, 2025
0211fed
chore: add changeset for PR #1810
Sep 19, 2025
cf4d070
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 22, 2025
95df8d3
chore: add changeset for PR #1810
Sep 22, 2025
150865c
update validation service for the github
AayushSaini101 Sep 22, 2025
e04600f
chore: add changeset for PR #1810
Sep 22, 2025
4c5be56
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
fcc864d
Update src/apps/api/middlewares/validation.middleware.ts
AayushSaini101 Sep 24, 2025
6c66199
chore: add changeset for PR #1810
Sep 24, 2025
2f69485
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
5328d62
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
407bacc
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
3b7159b
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
f601cf7
Update src/domains/services/validation.service.ts
AayushSaini101 Sep 24, 2025
25860cc
chore: add changeset for PR #1810
Sep 24, 2025
8943766
updateValidationservice
AayushSaini101 Sep 27, 2025
aa37d14
remove invalid comment
AayushSaini101 Sep 27, 2025
edb659c
chore: add changeset for PR #1810
Sep 27, 2025
14dc382
Merge branch 'master' into 1796-b
asyncapi-bot Oct 12, 2025
704d261
Merge branch 'master' into 1796-b
asyncapi-bot Oct 16, 2025
3b882ed
Add new custom resolver to fetch the reference from private template …
AayushSaini101 Jun 21, 2025
811bc08
update
AayushSaini101 Sep 7, 2025
bb0fb6c
remove config service test file
aayushRedHat Oct 19, 2025
32298a9
remove invalid statements
AayushSaini101 Oct 19, 2025
ad3b3b8
add missing dependencies
AayushSaini101 Oct 19, 2025
7662fca
remove warnings
AayushSaini101 Oct 19, 2025
40b4b50
update validation-service
AayushSaini101 Oct 19, 2025
d7db432
remove invalid file
AayushSaini101 Oct 19, 2025
98dfd4c
fix lint issue
AayushSaini101 Oct 19, 2025
75dda7b
update validation-service
AayushSaini101 Oct 19, 2025
5c23530
fix lint issue
AayushSaini101 Oct 19, 2025
d6d0402
chore: add changeset for PR #1810
Oct 19, 2025
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
33 changes: 33 additions & 0 deletions .changeset/1810.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
'@asyncapi/cli': minor
---

feat: add new custom resolver to fetch the reference from private repo

- 0213926: Add new custom resolver to fetch the reference from private template and add new command auth add
- 26037eb: Merge remote-tracking branch 'remote/master' into 1796-b
- 6473326: chore: separate cli and api

Signed-off-by: Shurtu-gal <[email protected]>
- d484f2f: update
- ab58365: remove invalid changes
- 932c09c: update package-lock.json
- ec5eb66: update package-lock.json
- 7e4b523: fix github jobs
- c7501a1: Fix elint issue
- 925b90a: remove uncessary files
- 5d651f7: remove invalid file
- 5d76066: update-changeset
- 5d89ce7: update-doc
- 3461288: update-suggestions
- 4f63af9: add new testcase
- 5d83ac7: add new testcases
- f1a4d39: add new test case for the validationService
- af11ce4: update test case
- 824bdb9: update changeset
- cf4d070: Update src/domains/services/validation.service.ts

Co-authored-by: Fran Méndez <[email protected]>
- 150865c: update validation service for the github


32 changes: 32 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ USAGE
* [`asyncapi bundle`](#asyncapi-bundle)
* [`asyncapi config`](#asyncapi-config)
* [`asyncapi config analytics`](#asyncapi-config-analytics)
* [`asyncapi config auth add PATTERN TOKEN`](#asyncapi-config-auth-add-pattern-token)
* [`asyncapi config context`](#asyncapi-config-context)
* [`asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH`](#asyncapi-config-context-add-context-name-spec-file-path)
* [`asyncapi config context current`](#asyncapi-config-context-current)
Expand Down Expand Up @@ -170,6 +171,37 @@ DESCRIPTION

_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v3.2.0/src/commands/config/analytics.ts)_

## `asyncapi config auth add PATTERN TOKEN`

Add an authentication config for resolving $ref files requiring HTTP Authorization.

```
USAGE
$ asyncapi config auth add PATTERN TOKEN [-a <value>] [-h <value>...]

ARGUMENTS
PATTERN Glob pattern for matching protected URLs (e.g. github.com/org/repo/**/*.*)
TOKEN Authentication token or environment variable reference (prefix with $, e.g. $GITHUB_TOKEN)

FLAGS
-a, --auth-type=<value> Authentication type (default is "Bearer")
-h, --header=<value>... Additional headers in key=value format

DESCRIPTION
Add an authentication config for resolving $ref files requiring HTTP Authorization.

EXAMPLES
$ asyncapi config auth add "https://github.com/org/repo/**/*" "ghp_XuYi7ZWQWjmrJpY2Kz3ET"

$ asyncapi config auth add "https://api.github.com/repos/org/repo/**/*" "$GITHUB_TOKEN"

$ asyncapi config auth add "https://private-registry.com/**/*" "my-token" --auth-type="Token"

$ asyncapi config auth add "https://api.example.com/**/*" "token123" --header="X-API-Key=abc123" --header="User-Agent=MyApp/1.0"
```

_See code: [src/commands/config/auth/add.ts](https://github.com/asyncapi/cli/blob/v3.2.0/src/commands/config/auth/add.ts)_

## `asyncapi config context`

Manage short aliases for full paths to AsyncAPI documents
Expand Down
1 change: 1 addition & 0 deletions scripts/enableAutoComplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function getShellConfig(shell) {
if (!allowedShells.includes(shell)) {
throw new Error(`Unsupported shell: ${shell}. Autocomplete only supports zsh and bash.`);
}
// eslint-disable-next-line security/detect-object-injection
return shellConfigs[shell];
}

Expand Down
1 change: 1 addition & 0 deletions src/apps/api/middlewares/validation.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
req: Request,
res: Response,
next: NextFunction,
): Promise<void> => {

Check warning on line 169 in src/apps/api/middlewares/validation.middleware.ts

View workflow job for this annotation

GitHub Actions / Test NodeJS PR - ubuntu-latest

Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed
// Check if the condition is met
if (options.condition && !options.condition(req)) {
return next();
Expand Down Expand Up @@ -203,6 +203,7 @@
__unstable: {
resolver: {
resolvers: [
// GitHub resolver for private repositories is automatically included by ValidationService
// @TODO: Add Cookie Based Resolvers after migration and understanding some
// details about how to use them in the new parser-js version.
],
Expand Down
76 changes: 76 additions & 0 deletions src/apps/cli/commands/config/auth/add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Args, Flags } from '@oclif/core';
import Command from '@cli/internal/base';
import { blueBright } from 'picocolors';
import { ConfigService, AuthEntry } from '@/domains/services/config.service';

export default class AuthAdd extends Command {
static description =
'Add an authentication config for resolving $ref files requiring HTTP Authorization.';

static args = {
pattern: Args.string({
required: true,
description:
'Glob pattern for matching protected URLs (e.g. github.com/org/repo/**/*.*)',
}),
token: Args.string({
required: true,
description:
'Authentication token or environment variable reference (prefix with $, e.g. $GITHUB_TOKEN)',
}),
};

static flags = {
'auth-type': Flags.string({
char: 'a',
description: 'Authentication type (default is "Bearer")',
}),
header: Flags.string({
char: 'h',
description:
'Additional header in key=value format; can be used multiple times',
multiple: true,
}),
};

async run() {
const { args, flags } = await this.parse(AuthAdd);

const isEnvVar = args.token.startsWith('$');
const tokenValue = isEnvVar ? args.token.slice(1) : args.token;

// Parse headers into an object
const headers: Record<string, string> = {};
if (flags.header) {
for (const headerEntry of flags.header) {
const [key, value] = headerEntry.split('=');
if (key && value) {
headers[key.trim()] = value.trim();
} else {
this.warn(`⚠️ Ignored invalid header format: ${headerEntry}`);
}
}
}

const entry: AuthEntry = {
pattern: args.pattern,
token: tokenValue,
authType: flags['auth-type'] || 'Bearer',
headers: Object.keys(headers).length ? headers : undefined,
};

try {
await ConfigService.addAuthEntry(entry);
this.log(
`✅ Auth config added for ${blueBright(args.pattern)} using ${
isEnvVar ? `env var (${tokenValue})` : 'raw token'
} with auth type ${blueBright(entry.authType || 'Bearer')}`
);
if (entry.headers) {
this.log(`Headers: ${JSON.stringify(entry.headers, null, 2)}`);
}
} catch (err) {
this.error(`❌ Failed to add auth config: ${(err as Error).message}`);
}
}
}
2 changes: 1 addition & 1 deletion src/apps/cli/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
export default class Validate extends Command {
static description = 'validate asyncapi file';
private validationService = new ValidationService();

static flags = {
...validateFlags(),
...proxyFlags(), // Merge proxyFlags with validateFlags
Expand Down
104 changes: 104 additions & 0 deletions src/domains/services/config.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import path from 'path';
import os from 'os';
import { promises as fs } from 'fs';
import minimatch from 'minimatch';

const CONFIG_DIR = path.join(os.homedir(), '.asyncapi');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');

export interface AuthEntry {
pattern: string;
token: string;
authType?: string;
headers?: Record<string, string>;
}

export interface AuthResult {
token: string;
authType: string;
headers: Record<string, string>;
}

interface Config {
auth?: AuthEntry[];
}

export class ConfigService {
/**
* Load config file (~/.asyncapi/config.json)
*/
static async loadConfig(): Promise<Config> {
try {
const content = await fs.readFile(CONFIG_FILE, 'utf8');
return JSON.parse(content) as Config;
} catch (err: any) {
if (err.code === 'ENOENT') {
return {}; // no config yet
}
throw new Error(`Error reading config file: ${err.message}`);
}
}

/**
* Save config back to file
*/
static async saveConfig(config: Config): Promise<void> {
await fs.mkdir(CONFIG_DIR, { recursive: true });
await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
}

/**
* Add or update an auth entry by merging with existing entry if present
*/
static async addAuthEntry(entry: AuthEntry): Promise<void> {
const config = await this.loadConfig();

// Ensure config.auth is initialized as an array
config.auth ??= [];

// Find existing entry by pattern
const existingEntry = config.auth.find(e => e.pattern === entry.pattern);

if (existingEntry) {
// Merge new entry into existing one
Object.assign(existingEntry, entry);
} else {
// No existing entry, add new one
config.auth.push(entry);
}

await this.saveConfig(config);
}

/**
* Reads auth config from ~/.asyncapi/config.json and
* returns auth info matching the given URL, or null if no match.
*
* @param url - URL to match against auth patterns
* @returns Auth info or null if no match found
*/
static async getAuthForUrl(url: string): Promise<AuthResult | null> {
const config = await this.loadConfig();

if (!config.auth || !Array.isArray(config.auth)) {
console.warn('⚠️ No valid "auth" array found in config');
return null;
}

for (const entry of config.auth) {
try {
if (minimatch(url, entry.pattern)) {
return {
token: entry.token,
authType: entry.authType || 'Bearer',
headers: entry.headers || {}
};
}
} catch (err: any) {
console.warn(`⚠️ Invalid pattern "${entry.pattern}": ${err.message}`);
}
}

return null;
}
}
Loading
Loading