@asyncapi/cli 4.1.1 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +4 -0
  2. package/assets/create-template/templates/default/package-lock.json +4 -3
  3. package/lib/apps/api/controllers/generate.controller.js +1 -3
  4. package/lib/apps/cli/commands/convert.d.ts +0 -2
  5. package/lib/apps/cli/commands/convert.js +9 -14
  6. package/lib/apps/cli/commands/format.d.ts +1 -3
  7. package/lib/apps/cli/commands/format.js +7 -10
  8. package/lib/apps/cli/commands/generate/client.js +5 -5
  9. package/lib/apps/cli/commands/generate/fromTemplate.d.ts +0 -25
  10. package/lib/apps/cli/commands/generate/fromTemplate.js +9 -17
  11. package/lib/apps/cli/commands/generate/models.js +3 -5
  12. package/lib/apps/cli/commands/optimize.js +11 -12
  13. package/lib/apps/cli/commands/start/preview.js +1 -1
  14. package/lib/apps/cli/commands/validate.js +2 -7
  15. package/lib/apps/cli/internal/base/BaseGeneratorCommand.js +3 -5
  16. package/lib/apps/cli/internal/base.d.ts +1 -1
  17. package/lib/apps/cli/internal/base.js +8 -7
  18. package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.d.ts +0 -25
  19. package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.js +1 -2
  20. package/lib/apps/cli/internal/globals.js +2 -1
  21. package/lib/domains/models/Context.js +3 -1
  22. package/lib/domains/models/Preview.js +9 -2
  23. package/lib/domains/models/SpecificationFile.d.ts +12 -0
  24. package/lib/domains/models/SpecificationFile.js +20 -3
  25. package/lib/domains/models/Studio.js +9 -2
  26. package/lib/domains/services/base.service.d.ts +26 -2
  27. package/lib/domains/services/base.service.js +23 -0
  28. package/lib/domains/services/convert.service.d.ts +13 -0
  29. package/lib/domains/services/convert.service.js +14 -3
  30. package/lib/domains/services/generator.service.d.ts +20 -2
  31. package/lib/domains/services/generator.service.js +21 -28
  32. package/lib/domains/services/validation.service.d.ts +16 -0
  33. package/lib/domains/services/validation.service.js +68 -57
  34. package/lib/index.d.ts +4 -0
  35. package/lib/index.js +7 -0
  36. package/lib/interfaces/index.d.ts +54 -12
  37. package/lib/utils/error-handler.d.ts +95 -0
  38. package/lib/utils/error-handler.js +134 -0
  39. package/lib/utils/proxy.d.ts +29 -0
  40. package/lib/utils/proxy.js +47 -0
  41. package/lib/utils/validation.d.ts +103 -0
  42. package/lib/utils/validation.js +159 -0
  43. package/oclif.manifest.json +1 -9
  44. package/package.json +10 -11
  45. package/scripts/generateTypesForGenerateCommand.js +1 -1
@@ -1,22 +1,37 @@
1
- import { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
1
+ import { AsyncAPIDocumentInterface, Diagnostic } from '@asyncapi/parser/cjs';
2
2
  import { OutputFormat } from '@stoplight/spectral-cli/dist/services/config';
3
+ /**
4
+ * Supported diagnostic output formats for validation results.
5
+ */
3
6
  export type DiagnosticsFormat = 'stylish' | 'json' | 'junit' | 'html' | 'text' | 'teamcity' | 'pretty';
7
+ /**
8
+ * Severity levels for validation diagnostics.
9
+ */
4
10
  export type SeverityKind = 'error' | 'warn' | 'info' | 'hint';
11
+ /**
12
+ * Adapter type for CLI or API usage.
13
+ */
5
14
  export type Adapter = 'cli' | 'api';
6
15
  import specs from '@asyncapi/specs';
7
16
  import { Router } from 'express';
8
17
  import { AsyncAPIConvertVersion } from '@asyncapi/converter';
18
+ /**
19
+ * Controller interface for Express routers.
20
+ */
9
21
  export interface Controller {
10
22
  basepath: string;
11
23
  boot(): Router | Promise<Router>;
12
24
  }
25
+ /**
26
+ * RFC 7807 Problem Details object.
27
+ */
13
28
  export interface Problem {
14
29
  type: string;
15
30
  title: string;
16
31
  status: number;
17
32
  detail?: string;
18
33
  instance?: string;
19
- [key: string]: any;
34
+ [key: string]: string | number | undefined;
20
35
  }
21
36
  export type AsyncAPIDocument = {
22
37
  asyncapi: string;
@@ -28,17 +43,28 @@ export interface AsyncAPIServiceOptions {
28
43
  source?: string;
29
44
  path?: string;
30
45
  }
31
- export interface ServiceResult<T = any> {
46
+ /**
47
+ * Standard service result wrapper for consistent response handling.
48
+ *
49
+ * @template T - The type of data returned on success
50
+ */
51
+ export interface ServiceResult<T = unknown> {
32
52
  success: boolean;
33
53
  data?: T;
34
54
  error?: string;
35
- diagnostics?: any[];
55
+ diagnostics?: Diagnostic[];
36
56
  }
57
+ /**
58
+ * Result of parsing an AsyncAPI document.
59
+ */
37
60
  export interface ParsedDocument {
38
61
  document: AsyncAPIDocumentInterface;
39
- diagnostics: any[];
62
+ diagnostics: Diagnostic[];
40
63
  status: 'valid' | 'invalid';
41
64
  }
65
+ /**
66
+ * Options for document validation.
67
+ */
42
68
  export interface ValidationOptions {
43
69
  'log-diagnostics'?: boolean;
44
70
  'diagnostics-format'?: `${OutputFormat}`;
@@ -47,10 +73,13 @@ export interface ValidationOptions {
47
73
  suppressWarnings?: string[];
48
74
  suppressAllWarnings?: boolean;
49
75
  }
76
+ /**
77
+ * Result of document validation.
78
+ */
50
79
  export interface ValidationResult {
51
80
  status: 'valid' | 'invalid';
52
81
  document?: AsyncAPIDocument;
53
- diagnostics?: any[];
82
+ diagnostics?: Diagnostic[];
54
83
  score?: number;
55
84
  }
56
85
  export interface ConversionOptions {
@@ -62,24 +91,37 @@ export interface ConversionResult {
62
91
  convertedDocument: string;
63
92
  originalFormat: string;
64
93
  }
94
+ /**
95
+ * Base URL mapping configuration for template generation.
96
+ */
65
97
  export interface IMapBaseUrlToFlag {
66
98
  url: string;
67
99
  folder: string;
68
100
  }
101
+ /**
102
+ * Configuration for npm registry authentication.
103
+ */
104
+ export interface RegistryConfig {
105
+ url?: string;
106
+ auth?: string;
107
+ token?: string;
108
+ }
109
+ /**
110
+ * Options for code generation from AsyncAPI documents.
111
+ */
69
112
  export interface GenerationOptions {
70
- templateParams?: Record<string, any>;
113
+ templateParams?: Record<string, unknown>;
71
114
  forceWrite?: boolean;
72
115
  install?: boolean;
73
116
  debug?: boolean;
74
117
  noOverwriteGlobs?: string[];
75
118
  disabledHooks?: Record<string, string>;
76
119
  mapBaseUrl?: IMapBaseUrlToFlag;
77
- registry?: {
78
- url?: string;
79
- auth?: string;
80
- token?: string;
81
- };
120
+ registry?: RegistryConfig;
82
121
  }
122
+ /**
123
+ * Result of a code generation operation.
124
+ */
83
125
  export interface GenerationResult {
84
126
  success: boolean;
85
127
  outputPath: string;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Error handling utilities for consistent error management across the CLI and API.
3
+ * Provides type-safe error handling and standardized error messages.
4
+ */
5
+ /**
6
+ * Extracts a safe error message from any caught error.
7
+ * Handles various error types including Error objects, strings, and unknown types.
8
+ *
9
+ * @param error - The caught error (can be any type)
10
+ * @param fallbackMessage - Default message if error cannot be parsed
11
+ * @returns A string error message
12
+ *
13
+ * @example
14
+ * try {
15
+ * await riskyOperation();
16
+ * } catch (error) {
17
+ * const message = getErrorMessage(error, 'Operation failed');
18
+ * console.error(message);
19
+ * }
20
+ */
21
+ export declare function getErrorMessage(error: unknown, fallbackMessage?: string): string;
22
+ /**
23
+ * Extracts the error stack trace if available.
24
+ *
25
+ * @param error - The caught error
26
+ * @returns Stack trace string or undefined
27
+ */
28
+ export declare function getErrorStack(error: unknown): string | undefined;
29
+ /**
30
+ * Type guard to check if a value is an Error instance.
31
+ *
32
+ * @param value - Value to check
33
+ * @returns True if value is an Error
34
+ */
35
+ export declare function isError(value: unknown): value is Error;
36
+ /**
37
+ * Type guard to check if an error has a specific code property.
38
+ * Useful for Node.js system errors (ENOENT, EACCES, etc.)
39
+ *
40
+ * @param error - The error to check
41
+ * @param code - The error code to match
42
+ * @returns True if error has the specified code
43
+ *
44
+ * @example
45
+ * try {
46
+ * await fs.readFile(path);
47
+ * } catch (error) {
48
+ * if (hasErrorCode(error, 'ENOENT')) {
49
+ * console.log('File not found');
50
+ * }
51
+ * }
52
+ */
53
+ export declare function hasErrorCode(error: unknown, code: string): boolean;
54
+ /**
55
+ * Wraps an async function to catch and transform errors.
56
+ * Useful for standardizing error handling in command handlers.
57
+ *
58
+ * @param fn - Async function to wrap
59
+ * @param errorHandler - Function to handle caught errors
60
+ * @returns Wrapped function
61
+ *
62
+ * @example
63
+ * const safeRun = withErrorHandling(
64
+ * async () => await riskyOperation(),
65
+ * (error) => console.error('Failed:', getErrorMessage(error))
66
+ * );
67
+ */
68
+ export declare function withErrorHandling<T, Args extends unknown[]>(fn: (...args: Args) => Promise<T>, errorHandler: (error: unknown) => void): (...args: Args) => Promise<T | undefined>;
69
+ /**
70
+ * Creates a typed error result for service functions.
71
+ * Alternative to throwing errors - returns a result object instead.
72
+ */
73
+ export interface ErrorResult {
74
+ success: false;
75
+ error: string;
76
+ code?: string;
77
+ details?: Record<string, unknown>;
78
+ }
79
+ export interface SuccessResult<T> {
80
+ success: true;
81
+ data: T;
82
+ }
83
+ export type Result<T> = SuccessResult<T> | ErrorResult;
84
+ /**
85
+ * Creates a success result.
86
+ */
87
+ export declare function success<T>(data: T): SuccessResult<T>;
88
+ /**
89
+ * Creates an error result.
90
+ */
91
+ export declare function failure(error: string, code?: string, details?: Record<string, unknown>): ErrorResult;
92
+ /**
93
+ * Creates an error result from a caught error.
94
+ */
95
+ export declare function failureFromError(error: unknown, fallbackMessage?: string): ErrorResult;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * Error handling utilities for consistent error management across the CLI and API.
4
+ * Provides type-safe error handling and standardized error messages.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getErrorMessage = getErrorMessage;
8
+ exports.getErrorStack = getErrorStack;
9
+ exports.isError = isError;
10
+ exports.hasErrorCode = hasErrorCode;
11
+ exports.withErrorHandling = withErrorHandling;
12
+ exports.success = success;
13
+ exports.failure = failure;
14
+ exports.failureFromError = failureFromError;
15
+ const tslib_1 = require("tslib");
16
+ /**
17
+ * Extracts a safe error message from any caught error.
18
+ * Handles various error types including Error objects, strings, and unknown types.
19
+ *
20
+ * @param error - The caught error (can be any type)
21
+ * @param fallbackMessage - Default message if error cannot be parsed
22
+ * @returns A string error message
23
+ *
24
+ * @example
25
+ * try {
26
+ * await riskyOperation();
27
+ * } catch (error) {
28
+ * const message = getErrorMessage(error, 'Operation failed');
29
+ * console.error(message);
30
+ * }
31
+ */
32
+ function getErrorMessage(error, fallbackMessage = 'An unknown error occurred') {
33
+ if (error instanceof Error) {
34
+ return error.message;
35
+ }
36
+ if (typeof error === 'string') {
37
+ return error;
38
+ }
39
+ if (error && typeof error === 'object' && 'message' in error) {
40
+ return String(error.message);
41
+ }
42
+ return fallbackMessage;
43
+ }
44
+ /**
45
+ * Extracts the error stack trace if available.
46
+ *
47
+ * @param error - The caught error
48
+ * @returns Stack trace string or undefined
49
+ */
50
+ function getErrorStack(error) {
51
+ if (error instanceof Error) {
52
+ return error.stack;
53
+ }
54
+ return undefined;
55
+ }
56
+ /**
57
+ * Type guard to check if a value is an Error instance.
58
+ *
59
+ * @param value - Value to check
60
+ * @returns True if value is an Error
61
+ */
62
+ function isError(value) {
63
+ return value instanceof Error;
64
+ }
65
+ /**
66
+ * Type guard to check if an error has a specific code property.
67
+ * Useful for Node.js system errors (ENOENT, EACCES, etc.)
68
+ *
69
+ * @param error - The error to check
70
+ * @param code - The error code to match
71
+ * @returns True if error has the specified code
72
+ *
73
+ * @example
74
+ * try {
75
+ * await fs.readFile(path);
76
+ * } catch (error) {
77
+ * if (hasErrorCode(error, 'ENOENT')) {
78
+ * console.log('File not found');
79
+ * }
80
+ * }
81
+ */
82
+ function hasErrorCode(error, code) {
83
+ return (error !== null &&
84
+ typeof error === 'object' &&
85
+ 'code' in error &&
86
+ error.code === code);
87
+ }
88
+ /**
89
+ * Wraps an async function to catch and transform errors.
90
+ * Useful for standardizing error handling in command handlers.
91
+ *
92
+ * @param fn - Async function to wrap
93
+ * @param errorHandler - Function to handle caught errors
94
+ * @returns Wrapped function
95
+ *
96
+ * @example
97
+ * const safeRun = withErrorHandling(
98
+ * async () => await riskyOperation(),
99
+ * (error) => console.error('Failed:', getErrorMessage(error))
100
+ * );
101
+ */
102
+ function withErrorHandling(fn, errorHandler) {
103
+ return (...args) => tslib_1.__awaiter(this, void 0, void 0, function* () {
104
+ try {
105
+ return yield fn(...args);
106
+ }
107
+ catch (error) {
108
+ errorHandler(error);
109
+ return undefined;
110
+ }
111
+ });
112
+ }
113
+ /**
114
+ * Creates a success result.
115
+ */
116
+ function success(data) {
117
+ return { success: true, data };
118
+ }
119
+ /**
120
+ * Creates an error result.
121
+ */
122
+ function failure(error, code, details) {
123
+ return { success: false, error, code, details };
124
+ }
125
+ /**
126
+ * Creates an error result from a caught error.
127
+ */
128
+ function failureFromError(error, fallbackMessage = 'An unknown error occurred') {
129
+ return {
130
+ success: false,
131
+ error: getErrorMessage(error, fallbackMessage),
132
+ details: isError(error) ? { stack: error.stack } : undefined,
133
+ };
134
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Utility functions for proxy configuration.
3
+ * Centralizes proxy URL handling to avoid code duplication across commands.
4
+ */
5
+ /**
6
+ * Applies proxy configuration to a file path or URL.
7
+ * If both proxyHost and proxyPort are provided, appends the proxy URL to the path.
8
+ *
9
+ * @param filePath - The original file path or URL
10
+ * @param proxyHost - The proxy host name (optional)
11
+ * @param proxyPort - The proxy port number (optional)
12
+ * @returns The file path with proxy configuration appended, or the original path
13
+ *
14
+ * @example
15
+ * applyProxyToPath('./asyncapi.yaml', 'localhost', '8080')
16
+ * // Returns: './asyncapi.yaml+http://localhost:8080'
17
+ *
18
+ * applyProxyToPath('./asyncapi.yaml')
19
+ * // Returns: './asyncapi.yaml'
20
+ */
21
+ export declare function applyProxyToPath(filePath: string | undefined, proxyHost?: string, proxyPort?: string | number): string | undefined;
22
+ /**
23
+ * Builds a proxy URL from host and port.
24
+ *
25
+ * @param proxyHost - The proxy host name
26
+ * @param proxyPort - The proxy port number
27
+ * @returns The proxy URL or undefined if either parameter is missing
28
+ */
29
+ export declare function buildProxyUrl(proxyHost?: string, proxyPort?: string | number): string | undefined;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Utility functions for proxy configuration.
4
+ * Centralizes proxy URL handling to avoid code duplication across commands.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.applyProxyToPath = applyProxyToPath;
8
+ exports.buildProxyUrl = buildProxyUrl;
9
+ /**
10
+ * Applies proxy configuration to a file path or URL.
11
+ * If both proxyHost and proxyPort are provided, appends the proxy URL to the path.
12
+ *
13
+ * @param filePath - The original file path or URL
14
+ * @param proxyHost - The proxy host name (optional)
15
+ * @param proxyPort - The proxy port number (optional)
16
+ * @returns The file path with proxy configuration appended, or the original path
17
+ *
18
+ * @example
19
+ * applyProxyToPath('./asyncapi.yaml', 'localhost', '8080')
20
+ * // Returns: './asyncapi.yaml+http://localhost:8080'
21
+ *
22
+ * applyProxyToPath('./asyncapi.yaml')
23
+ * // Returns: './asyncapi.yaml'
24
+ */
25
+ function applyProxyToPath(filePath, proxyHost, proxyPort) {
26
+ if (!filePath) {
27
+ return filePath;
28
+ }
29
+ if (proxyHost && proxyPort) {
30
+ const proxyUrl = `http://${proxyHost}:${proxyPort}`;
31
+ return `${filePath}+${proxyUrl}`;
32
+ }
33
+ return filePath;
34
+ }
35
+ /**
36
+ * Builds a proxy URL from host and port.
37
+ *
38
+ * @param proxyHost - The proxy host name
39
+ * @param proxyPort - The proxy port number
40
+ * @returns The proxy URL or undefined if either parameter is missing
41
+ */
42
+ function buildProxyUrl(proxyHost, proxyPort) {
43
+ if (proxyHost && proxyPort) {
44
+ return `http://${proxyHost}:${proxyPort}`;
45
+ }
46
+ return undefined;
47
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Input validation utilities for CLI commands and API endpoints.
3
+ * Provides reusable validation functions with consistent error messages.
4
+ */
5
+ /**
6
+ * Validates that a file path is provided and not empty.
7
+ *
8
+ * @param filePath - The file path to validate
9
+ * @param fieldName - Name of the field for error messages
10
+ * @returns Validation result with error message if invalid
11
+ */
12
+ export declare function validateFilePath(filePath: string | undefined, fieldName?: string): {
13
+ valid: true;
14
+ value: string;
15
+ } | {
16
+ valid: false;
17
+ error: string;
18
+ };
19
+ /**
20
+ * Validates that a value is one of the allowed options.
21
+ *
22
+ * @param value - The value to validate
23
+ * @param allowedValues - Array of allowed values
24
+ * @param fieldName - Name of the field for error messages
25
+ * @returns Validation result
26
+ */
27
+ export declare function validateEnum<T extends string>(value: string | undefined, allowedValues: readonly T[], fieldName?: string): {
28
+ valid: true;
29
+ value: T;
30
+ } | {
31
+ valid: false;
32
+ error: string;
33
+ };
34
+ /**
35
+ * Validates that a port number is valid.
36
+ *
37
+ * @param port - The port to validate
38
+ * @param fieldName - Name of the field for error messages
39
+ * @returns Validation result
40
+ */
41
+ export declare function validatePort(port: string | number | undefined, fieldName?: string): {
42
+ valid: true;
43
+ value: number;
44
+ } | {
45
+ valid: false;
46
+ error: string;
47
+ };
48
+ /**
49
+ * Validates a URL string.
50
+ *
51
+ * @param url - The URL to validate
52
+ * @param fieldName - Name of the field for error messages
53
+ * @returns Validation result
54
+ */
55
+ export declare function validateUrl(url: string | undefined, fieldName?: string): {
56
+ valid: true;
57
+ value: string;
58
+ } | {
59
+ valid: false;
60
+ error: string;
61
+ };
62
+ /**
63
+ * Validates that a value is a non-empty string.
64
+ *
65
+ * @param value - The value to validate
66
+ * @param fieldName - Name of the field for error messages
67
+ * @returns Validation result
68
+ */
69
+ export declare function validateNonEmptyString(value: string | undefined, fieldName?: string): {
70
+ valid: true;
71
+ value: string;
72
+ } | {
73
+ valid: false;
74
+ error: string;
75
+ };
76
+ /**
77
+ * Validates that a version string matches semantic versioning pattern.
78
+ *
79
+ * @param version - The version string to validate
80
+ * @param fieldName - Name of the field for error messages
81
+ * @returns Validation result
82
+ */
83
+ export declare function validateVersion(version: string | undefined, fieldName?: string): {
84
+ valid: true;
85
+ value: string;
86
+ } | {
87
+ valid: false;
88
+ error: string;
89
+ };
90
+ /**
91
+ * Type guard to check if a value is defined (not null or undefined).
92
+ *
93
+ * @param value - Value to check
94
+ * @returns True if value is defined
95
+ */
96
+ export declare function isDefined<T>(value: T | null | undefined): value is T;
97
+ /**
98
+ * Type guard to check if a value is a non-empty array.
99
+ *
100
+ * @param value - Value to check
101
+ * @returns True if value is a non-empty array
102
+ */
103
+ export declare function isNonEmptyArray<T>(value: T[] | null | undefined): value is [T, ...T[]];
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * Input validation utilities for CLI commands and API endpoints.
4
+ * Provides reusable validation functions with consistent error messages.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.validateFilePath = validateFilePath;
8
+ exports.validateEnum = validateEnum;
9
+ exports.validatePort = validatePort;
10
+ exports.validateUrl = validateUrl;
11
+ exports.validateNonEmptyString = validateNonEmptyString;
12
+ exports.validateVersion = validateVersion;
13
+ exports.isDefined = isDefined;
14
+ exports.isNonEmptyArray = isNonEmptyArray;
15
+ /**
16
+ * Validates that a file path is provided and not empty.
17
+ *
18
+ * @param filePath - The file path to validate
19
+ * @param fieldName - Name of the field for error messages
20
+ * @returns Validation result with error message if invalid
21
+ */
22
+ function validateFilePath(filePath, fieldName = 'file path') {
23
+ if (!filePath || filePath.trim() === '') {
24
+ return {
25
+ valid: false,
26
+ error: `${fieldName} is required and cannot be empty`,
27
+ };
28
+ }
29
+ return { valid: true, value: filePath.trim() };
30
+ }
31
+ /**
32
+ * Validates that a value is one of the allowed options.
33
+ *
34
+ * @param value - The value to validate
35
+ * @param allowedValues - Array of allowed values
36
+ * @param fieldName - Name of the field for error messages
37
+ * @returns Validation result
38
+ */
39
+ function validateEnum(value, allowedValues, fieldName = 'value') {
40
+ if (!value) {
41
+ return {
42
+ valid: false,
43
+ error: `${fieldName} is required`,
44
+ };
45
+ }
46
+ if (!allowedValues.includes(value)) {
47
+ return {
48
+ valid: false,
49
+ error: `${fieldName} must be one of: ${allowedValues.join(', ')}`,
50
+ };
51
+ }
52
+ return { valid: true, value: value };
53
+ }
54
+ /**
55
+ * Validates that a port number is valid.
56
+ *
57
+ * @param port - The port to validate
58
+ * @param fieldName - Name of the field for error messages
59
+ * @returns Validation result
60
+ */
61
+ function validatePort(port, fieldName = 'port') {
62
+ if (port === undefined || port === '') {
63
+ return {
64
+ valid: false,
65
+ error: `${fieldName} is required`,
66
+ };
67
+ }
68
+ const portNum = typeof port === 'string' ? parseInt(port, 10) : port;
69
+ if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
70
+ return {
71
+ valid: false,
72
+ error: `${fieldName} must be a valid port number (1-65535)`,
73
+ };
74
+ }
75
+ return { valid: true, value: portNum };
76
+ }
77
+ /**
78
+ * Validates a URL string.
79
+ *
80
+ * @param url - The URL to validate
81
+ * @param fieldName - Name of the field for error messages
82
+ * @returns Validation result
83
+ */
84
+ function validateUrl(url, fieldName = 'URL') {
85
+ if (!url || url.trim() === '') {
86
+ return {
87
+ valid: false,
88
+ error: `${fieldName} is required`,
89
+ };
90
+ }
91
+ try {
92
+ new URL(url);
93
+ return { valid: true, value: url };
94
+ }
95
+ catch (_a) {
96
+ return {
97
+ valid: false,
98
+ error: `${fieldName} is not a valid URL`,
99
+ };
100
+ }
101
+ }
102
+ /**
103
+ * Validates that a value is a non-empty string.
104
+ *
105
+ * @param value - The value to validate
106
+ * @param fieldName - Name of the field for error messages
107
+ * @returns Validation result
108
+ */
109
+ function validateNonEmptyString(value, fieldName = 'value') {
110
+ if (!value || value.trim() === '') {
111
+ return {
112
+ valid: false,
113
+ error: `${fieldName} is required and cannot be empty`,
114
+ };
115
+ }
116
+ return { valid: true, value: value.trim() };
117
+ }
118
+ /**
119
+ * Validates that a version string matches semantic versioning pattern.
120
+ *
121
+ * @param version - The version string to validate
122
+ * @param fieldName - Name of the field for error messages
123
+ * @returns Validation result
124
+ */
125
+ function validateVersion(version, fieldName = 'version') {
126
+ if (!version) {
127
+ return {
128
+ valid: false,
129
+ error: `${fieldName} is required`,
130
+ };
131
+ }
132
+ // Matches patterns like 1.0.0, 2.0.0, 3.0.0, etc.
133
+ const semverPattern = /^\d+\.\d+\.\d+$/;
134
+ if (!semverPattern.test(version)) {
135
+ return {
136
+ valid: false,
137
+ error: `${fieldName} must be a valid semantic version (e.g., 3.0.0)`,
138
+ };
139
+ }
140
+ return { valid: true, value: version };
141
+ }
142
+ /**
143
+ * Type guard to check if a value is defined (not null or undefined).
144
+ *
145
+ * @param value - Value to check
146
+ * @returns True if value is defined
147
+ */
148
+ function isDefined(value) {
149
+ return value !== null && value !== undefined;
150
+ }
151
+ /**
152
+ * Type guard to check if a value is a non-empty array.
153
+ *
154
+ * @param value - Value to check
155
+ * @returns True if value is a non-empty array
156
+ */
157
+ function isNonEmptyArray(value) {
158
+ return Array.isArray(value) && value.length > 0;
159
+ }