Skip to content

Commit fd8e700

Browse files
Do not interpolate non string values automatically (#10183)
fix #10182 Only interpolate options with other options values if the value is a string, number or boolean. As its most likely not going to produce the expected result with array or objects. This delegate the interpolation for those to the emitters.
1 parent dafe925 commit fd8e700

3 files changed

Lines changed: 45 additions & 2 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
changeKind: fix
3+
packages:
4+
- "@typespec/compiler"
5+
---
6+
7+
Do not interpolate non primitive values in config automatically
8+
```yaml
9+
file-type: ["json", "yaml"]
10+
output-file: "openapi.{file-type}"
11+
```
12+
Will not be interpolated as `openapi.json,yaml` but keep the placeholder `{file-type}` intact for the emitter to handle.

packages/compiler/src/config/config-interpolation.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,13 @@ export function resolveValues<T extends Record<string, unknown>>(
114114
resolvingValues.delete(keyPath);
115115
return value;
116116
}
117-
const replaced = value.replace(VariableInterpolationRegex, (_, expression) => {
118-
return (resolveExpression(expression) as string) ?? `{${expression}}`;
117+
const replaced = value.replace(VariableInterpolationRegex, (match, expression) => {
118+
const resolved = resolveExpression(expression);
119+
return typeof resolved === "string" ||
120+
typeof resolved === "number" ||
121+
typeof resolved === "boolean"
122+
? String(resolved)
123+
: match;
119124
});
120125
resolvingValues.delete(keyPath);
121126
return replaced;

packages/compiler/test/config/config-interpolation.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,32 @@ describe("compiler: config interpolation", () => {
133133
},
134134
]);
135135
});
136+
137+
it("does not interpolate variables that resolve to non-string values", () => {
138+
const [resolved, diagnostics] = resolveValues({
139+
"output-file": "openapi.{file-type}",
140+
"file-type": ["yaml", "json"] as any,
141+
});
142+
expectDiagnosticEmpty(diagnostics);
143+
deepStrictEqual(resolved, {
144+
"output-file": "openapi.{file-type}",
145+
"file-type": ["yaml", "json"],
146+
});
147+
});
148+
149+
it("interpolates number and boolean values", () => {
150+
const [resolved, diagnostics] = resolveValues({
151+
path: "v{version}/debug-{debug}",
152+
version: 3 as any,
153+
debug: true as any,
154+
});
155+
expectDiagnosticEmpty(diagnostics);
156+
deepStrictEqual(resolved, {
157+
path: "v3/debug-true",
158+
version: 3,
159+
debug: true,
160+
});
161+
});
136162
});
137163

138164
describe("expandConfigVariables", () => {

0 commit comments

Comments
 (0)