Advanced object merging utilities with macro interpolation support and configurable array merging strategies for configuration processing and composition.
Performs strict merging that fails when conflicting values are encountered, ensuring configuration consistency.
function strictMerge(a: any, b: any, path?: JsonPath): any;Usage Example:
import { strictMerge } from "@autorest/common";
const baseConfig = {
timeout: 30,
retries: 3,
endpoints: {
api: "https://api.example.com"
}
};
const userConfig = {
retries: 5,
debug: true,
endpoints: {
auth: "https://auth.example.com"
}
};
try {
const merged = strictMerge(baseConfig, userConfig);
// Result: { timeout: 30, retries: 5, debug: true, endpoints: { api: "...", auth: "..." } }
} catch (error) {
// Throws if conflicting values found (e.g., different values for same key)
console.error("Configuration conflict:", error.message);
}Advanced merging with configurable strategies for arrays and macro interpolation support.
function mergeOverwriteOrAppend(
higherPriority: any,
lowerPriority: any,
options?: MergeOptions,
path?: JsonPath
): any;
interface MergeOptions {
interpolationContext?: any;
arrayMergeStrategy?: ArrayMergingStrategy;
concatListPathFilter?: (path: JsonPath) => boolean;
}
type ArrayMergingStrategy = "high-pri-first" | "low-pri-first";Usage Examples:
import { mergeOverwriteOrAppend, MergeOptions } from "@autorest/common";
// Basic merge with high priority first (default)
const config1 = { plugins: ["a", "b"], timeout: 30 };
const config2 = { plugins: ["c", "d"], debug: true };
const merged = mergeOverwriteOrAppend(config1, config2);
// Result: { plugins: ["a", "b", "c", "d"], timeout: 30, debug: true }
// Custom array strategy
const options: MergeOptions = {
arrayMergeStrategy: "low-pri-first"
};
const mergedLowFirst = mergeOverwriteOrAppend(config1, config2, options);
// Result: { plugins: ["c", "d", "a", "b"], timeout: 30, debug: true }
// With path filtering for concatenation
const pathFilterOptions: MergeOptions = {
concatListPathFilter: (path) => path.includes("includePaths")
};
const config3 = { includePaths: ["src/"], excludePaths: ["temp/"] };
const config4 = { includePaths: ["lib/"], excludePaths: ["dist/"] };
const filteredMerge = mergeOverwriteOrAppend(config3, config4, pathFilterOptions);
// includePaths will be concatenated, excludePaths will follow normal array mergeResolves interpolated values using macro expansion syntax with $(variableName) patterns.
function resolveRValue(
value: any,
propertyName: string,
higherPriority: any,
lowerPriority: any,
jsAware?: number
): any;Usage Example:
import { resolveRValue } from "@autorest/common";
const context = {
baseUrl: "https://api.example.com",
version: "v1",
timeout: 30000
};
const config = {
endpoint: "$(baseUrl)/$(version)/users",
requestTimeout: "$(timeout)",
fallbackUrl: "$(baseUrl)/health"
};
// Resolve interpolated values
const resolvedEndpoint = resolveRValue(
config.endpoint,
"endpoint",
context,
config
);
// Result: "https://api.example.com/v1/users"
const resolvedTimeout = resolveRValue(
config.requestTimeout,
"requestTimeout",
context,
config
);
// Result: 30000 (number, not string)import { mergeOverwriteOrAppend, resolveRValue } from "@autorest/common";
const baseConfig = {
apiUrl: "https://api.example.com",
version: "v2",
timeout: 5000
};
const userConfig = {
endpoints: {
users: "$(apiUrl)/$(version)/users",
posts: "$(apiUrl)/$(version)/posts"
},
retryTimeout: "$(timeout)"
};
const options = {
interpolationContext: baseConfig
};
const merged = mergeOverwriteOrAppend(baseConfig, userConfig, options);
// Automatically resolves $(apiUrl), $(version), and $(timeout) in userConfig
// Result: {
// apiUrl: "https://api.example.com",
// version: "v2",
// timeout: 5000,
// endpoints: {
// users: "https://api.example.com/v2/users",
// posts: "https://api.example.com/v2/posts"
// },
// retryTimeout: 5000
// }import { mergeOverwriteOrAppend } from "@autorest/common";
const config1 = {
scripts: ["build", "test"],
dependencies: ["lodash"],
includePaths: ["src/"]
};
const config2 = {
scripts: ["lint", "deploy"],
dependencies: ["axios"],
includePaths: ["lib/"]
};
// Only concatenate arrays for specific paths
const options = {
concatListPathFilter: (path) => path.includes("includePaths")
};
const result = mergeOverwriteOrAppend(config1, config2, options);
// scripts and dependencies follow normal array merge (high-pri-first)
// includePaths gets concatenated: ["src/", "lib/"]import { mergeOverwriteOrAppend } from "@autorest/common";
const baseConfig = {
database: {
host: "localhost",
port: 5432
},
redis: {
host: "localhost",
port: 6379
}
};
const envConfig = {
environment: "production",
database: {
host: "$(environment)-db.example.com",
ssl: true
},
redis: {
host: "$(environment)-redis.example.com"
}
};
const options = {
interpolationContext: { environment: "prod" }
};
const merged = mergeOverwriteOrAppend(baseConfig, envConfig, options);
// Result: {
// environment: "production",
// database: {
// host: "prod-db.example.com",
// port: 5432,
// ssl: true
// },
// redis: {
// host: "prod-redis.example.com",
// port: 6379
// }
// }Strict merge throws errors for conflicting values:
import { strictMerge } from "@autorest/common";
try {
const config1 = { timeout: 30, debug: false };
const config2 = { timeout: 60, verbose: true }; // timeout conflict
const merged = strictMerge(config1, config2);
} catch (error) {
console.error("Merge conflict:", error.message);
// Error: 'timeout' has incompatible values (30, 60)
}Array conflicts in strict merge:
try {
const config1 = { plugins: ["a", "b"] };
const config2 = { plugins: ["c", "d"] }; // array conflict
const merged = strictMerge(config1, config2);
} catch (error) {
console.error("Array conflict:", error.message);
// Error: 'plugins' has two arrays that are incompatible
}// JsonPath from @azure-tools/datastore dependency
type JsonPath = (string | number)[];