Skip to content

Commit 2fbc30b

Browse files
committed
reduce config selection via defaults if needed
1 parent f3aaba9 commit 2fbc30b

File tree

4 files changed

+46
-10
lines changed

4 files changed

+46
-10
lines changed

packages/core/src/config/collection-types.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ governing permissions and limitations under the License.
1111
*/
1212
import { type HttpsSteps } from "../core/formats/https-fmt.js";
1313
import { EncodingTypes } from "../core/request/body-template.js";
14-
import { type ConfigMapping } from "../core/schema/core/config-space.js";
15-
16-
export type Config = Record<string, string | ConfigMapping>;
14+
import { type ConfigMap } from "../core/schema/core/config-space.js";
1715

1816
export type Helper = {
1917
config: string;
@@ -28,8 +26,8 @@ export type AssetParseError = { path: string; error: any };
2826
export type Configuration = {
2927
name: string;
3028
path: string;
31-
config?: Config;
32-
defaults?: Record<string, string | ConfigMapping>;
29+
config?: ConfigMap;
30+
defaults?: ConfigMap;
3331
mixin?: string | string[];
3432
import?: ConfigurationImports;
3533
export?: string;

packages/core/src/core/endpoint-environment.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function createEndpointEnvironment({
5656
const environment = new ScriptEnvironment({
5757
name: endpoint.configuration.name,
5858
config: endpoint.configuration.config,
59+
defaults: endpoint.configuration.defaults,
5960
input: values,
6061
runtime: {
6162
false: false,

packages/core/src/core/schema/core/config-space.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,24 @@ import {
2121
import { arrayIntoObject, mapObject } from "../../../util/mapping.js";
2222
import { uniqReducer } from "../../../util/uniq-reducer.js";
2323

24+
export type ConfigMap = Record<string, ConfigMapping>;
25+
2426
export type ConfigMapping =
2527
| string
2628
| {
27-
[key: string]: Record<string, ConfigMapping>;
29+
[key: string]: ConfigMap;
2830
};
2931

3032
export class ConfigSpace {
3133
options: Record<string, string>[];
3234
possibilities: Record<string, string>[];
33-
mapping: Record<string, ConfigMapping>;
35+
mapping: ConfigMap;
36+
defaults: ConfigMap;
37+
chosen: Record<string, string> = {};
3438

35-
constructor(mapping: Record<string, ConfigMapping>) {
39+
constructor(mapping: ConfigMap, defaults?: ConfigMap) {
3640
this.options = enumerateConfigs((this.mapping = mapping));
41+
this.defaults = defaults ?? {};
3742

3843
this.possibilities = this.options.slice();
3944
}
@@ -43,6 +48,7 @@ export class ConfigSpace {
4348
}
4449

4550
choose(config: Record<string, unknown>) {
51+
Object.assign(this.chosen, config);
4652
this.possibilities = this.possibilities.filter((possibility) =>
4753
compatible(possibility, config),
4854
);
@@ -184,14 +190,29 @@ export class ConfigSpace {
184190

185191
// reduce alternatives down to those that are compatible with the
186192
// current possibilities and don't override any data in the natural interpretation.
187-
const selected = alternatives.filter(
193+
let selected = alternatives.filter(
188194
({ option }) =>
189195
compatible(option, compatibleNature) &&
190196
this.possibilities.some((possibility) =>
191197
compatible({ ...option, ...compatibleNature }, possibility),
192198
),
193199
);
194200

201+
if (selected.length > 1) {
202+
const inferred = {
203+
...this.chosen,
204+
...implied(...selected.map(({ option }) => option)),
205+
};
206+
207+
selected = selected.filter(({ option }) =>
208+
Object.entries(option).every(
209+
([k, v]) =>
210+
inferred[k] ??
211+
(resolveDefault(this.defaults[k], inferred) ?? v) == v,
212+
),
213+
);
214+
}
215+
195216
// rewrite any other mappings from the natural interpretation to the selected one.
196217
const rewritten = other.flatMap((pattern) =>
197218
naturally.flatMap(({ pattern: from }) =>
@@ -418,3 +439,17 @@ function related(keys: string[], options: Record<string, string>[]) {
418439

419440
return keys;
420441
}
442+
443+
function resolveDefault(
444+
defaulted: ConfigMapping,
445+
values: Record<string, string>,
446+
): string | undefined {
447+
while (defaulted !== undefined) {
448+
if (typeof defaulted === "string") {
449+
return defaulted;
450+
}
451+
452+
const [k, v] = Object.entries(defaulted)[0];
453+
defaulted = v[values[k] ?? "default"];
454+
}
455+
}

packages/core/src/core/schema/core/script-environment.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export class ScriptEnvironment implements SchemaScriptEnvironment {
7575
constructor({
7676
name,
7777
config,
78+
defaults,
7879
input,
7980
runtime,
8081
resolve,
@@ -86,6 +87,7 @@ export class ScriptEnvironment implements SchemaScriptEnvironment {
8687
}: {
8788
name?: string;
8889
config?: Record<string, ConfigMapping>;
90+
defaults?: Record<string, ConfigMapping>;
8991
input?: Record<string, unknown>;
9092
runtime?: Record<string, unknown>;
9193
resolve?: ScriptDataResolver;
@@ -97,7 +99,7 @@ export class ScriptEnvironment implements SchemaScriptEnvironment {
9799
} = {}) {
98100
this.name = () => name;
99101
this.input = input ?? {};
100-
this.space = new ConfigSpace(config ?? {});
102+
this.space = new ConfigSpace(config ?? {}, defaults);
101103
this.space.choose(input ?? {});
102104

103105
this.resolver = (identifier, context) => {

0 commit comments

Comments
 (0)