(config: IRcFileConfig, rcFilePath: string)
| 250 | } |
| 251 | |
| 252 | function interpolateNpmVariables(config: IRcFileConfig, rcFilePath: string): IRcFileConfig { |
| 253 | // Quick check - return unchanged if no variables |
| 254 | if (!hasNpmVariables(config)) return config; |
| 255 | |
| 256 | // Find package.json |
| 257 | const packageJsonPath = findPackageJson(rcFilePath); |
| 258 | if (!packageJsonPath) { |
| 259 | const affectedFields: string[] = []; |
| 260 | if (config.sourcepath?.includes('$npm_package_')) affectedFields.push('sourcepath'); |
| 261 | if (config.outputfile?.includes('$npm_package_')) affectedFields.push('outputfile'); |
| 262 | if (config.version?.includes('$npm_package_')) affectedFields.push('version'); |
| 263 | if (config.espmethod?.includes('$npm_package_')) affectedFields.push('espmethod'); |
| 264 | if (config.define?.includes('$npm_package_')) affectedFields.push('define'); |
| 265 | if (config.basepath?.includes('$npm_package_')) affectedFields.push('basepath'); |
| 266 | if (config.exclude) |
| 267 | for (const [index, pattern] of config.exclude.entries()) |
| 268 | if (pattern.includes('$npm_package_')) affectedFields.push(`exclude[${index}]`); |
| 269 | |
| 270 | throw new Error( |
| 271 | `RC file uses npm package variables but package.json not found in ${path.dirname(rcFilePath)}\n` + |
| 272 | `Variables found in fields: ${affectedFields.join(', ')}\n` + |
| 273 | `Please ensure package.json exists in the same directory as your RC file.` |
| 274 | ); |
| 275 | } |
| 276 | |
| 277 | // Parse package.json |
| 278 | const packageJson = parsePackageJson(packageJsonPath); |
| 279 | |
| 280 | // Interpolation function |
| 281 | const interpolateString = (value: string): string => { |
| 282 | // Match $npm_package_ followed by field name (stops at _ + uppercase) |
| 283 | // This allows: version, repository_type, but stops at _STATIC |
| 284 | const regex = /\$npm_package_[\dA-Za-z]+(?:_[a-z][\dA-Za-z]*)*/g; |
| 285 | return value.replaceAll(regex, (match: string) => getNpmPackageVariable(packageJson, match) ?? match); |
| 286 | }; |
| 287 | |
| 288 | // Create new config with interpolated values |
| 289 | const result: IRcFileConfig = { ...config }; |
| 290 | |
| 291 | if (result.sourcepath) result.sourcepath = interpolateString(result.sourcepath); |
| 292 | if (result.outputfile) result.outputfile = interpolateString(result.outputfile); |
| 293 | if (result.espmethod) result.espmethod = interpolateString(result.espmethod); |
| 294 | if (result.define) result.define = interpolateString(result.define); |
| 295 | if (result.version) result.version = interpolateString(result.version); |
| 296 | if (result.basepath) result.basepath = interpolateString(result.basepath); |
| 297 | if (result.exclude) result.exclude = result.exclude.map((pattern) => interpolateString(pattern)); |
| 298 | |
| 299 | return result; |
| 300 | } |
| 301 | |
| 302 | function loadRcFile(rcPath: string): IRcFileConfig { |
| 303 | try { |
no test coverage detected