@kubb/studio 5.12.3 → 5.12.4
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.
- package/dist/index.cjs +108 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +108 -6
- package/dist/index.js.map +1 -1
- package/dist/{protocol-WYICLbSg.d.ts → protocol-C4loKcxw.d.cts} +33 -8
- package/dist/{protocol-WYICLbSg.d.cts → protocol-C4loKcxw.d.ts} +33 -8
- package/dist/protocol.cjs +3 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +2 -2
- package/dist/protocol.d.ts +2 -2
- package/dist/protocol.js +3 -1
- package/dist/protocol.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -230,7 +230,7 @@ function getElapsedMs(hrStart) {
|
|
|
230
230
|
}
|
|
231
231
|
//#endregion
|
|
232
232
|
//#region package.json
|
|
233
|
-
var version = "5.12.
|
|
233
|
+
var version = "5.12.4";
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region src/resolveConfig.ts
|
|
236
236
|
/**
|
|
@@ -586,6 +586,44 @@ async function rebuildExtension({ disk, studioOptions, kind, extensions }) {
|
|
|
586
586
|
});
|
|
587
587
|
}))(mergeOptions(disk.options ?? {}, studioOptions));
|
|
588
588
|
}
|
|
589
|
+
/** The root `output` members Studio may set, with the values each takes. The rest, `path` and `postGenerate` among them, stay with the config file. */
|
|
590
|
+
const OUTPUT_VALUES = {
|
|
591
|
+
barrel: (value) => value === false || isPlainObject(value) && Object.keys(value).length === 1 && (value.type === "named" || value.type === "all"),
|
|
592
|
+
format: (value) => value === false || [
|
|
593
|
+
"auto",
|
|
594
|
+
"prettier",
|
|
595
|
+
"biome",
|
|
596
|
+
"oxfmt"
|
|
597
|
+
].includes(value),
|
|
598
|
+
lint: (value) => value === false || [
|
|
599
|
+
"auto",
|
|
600
|
+
"eslint",
|
|
601
|
+
"biome",
|
|
602
|
+
"oxlint"
|
|
603
|
+
].includes(value),
|
|
604
|
+
clean: (value) => typeof value === "boolean",
|
|
605
|
+
defaultBanner: (value) => value === false || value === "simple" || value === "full"
|
|
606
|
+
};
|
|
607
|
+
/** Whether Studio may set the root `output` member `key`. */
|
|
608
|
+
function isOutputKey(key) {
|
|
609
|
+
return Object.hasOwn(OUTPUT_VALUES, key);
|
|
610
|
+
}
|
|
611
|
+
/** Whether Studio may set the root `output` member `key` to `value`. */
|
|
612
|
+
function isOutputValue({ key, value }) {
|
|
613
|
+
return isOutputKey(key) && OUTPUT_VALUES[key](value);
|
|
614
|
+
}
|
|
615
|
+
/** The members of `output` Studio may see and set. */
|
|
616
|
+
function pickOutput(output) {
|
|
617
|
+
return Object.fromEntries(Object.entries(output).filter(([key]) => isOutputKey(key)));
|
|
618
|
+
}
|
|
619
|
+
/** Merges Studio's valid `output` overrides, with `null` unsetting a member. */
|
|
620
|
+
function mergeOutput({ output, studio }) {
|
|
621
|
+
if (!isPlainObject(studio)) return output;
|
|
622
|
+
return mergeOptions(output, Object.fromEntries(Object.entries(studio).filter(([key, value]) => value === null ? isOutputKey(key) : isOutputValue({
|
|
623
|
+
key,
|
|
624
|
+
value
|
|
625
|
+
}))));
|
|
626
|
+
}
|
|
589
627
|
/**
|
|
590
628
|
* Merges Studio-provided adapter option overrides into the disk config's adapter, see {@link rebuildExtension}.
|
|
591
629
|
*/
|
|
@@ -643,14 +681,16 @@ function invalidEdit(edit) {
|
|
|
643
681
|
if (typeof operation !== "string" || !OPERATIONS.has(operation)) return `unknown operation ${JSON.stringify(operation)}`;
|
|
644
682
|
if (config !== void 0 && typeof config !== "string" && !Number.isSafeInteger(config)) return "config must name an entry or give its index";
|
|
645
683
|
if (operation === require_protocol.ConfigEditOperation.SET_INPUT) return typeof input === "string" && input.trim() ? void 0 : "the edit names no input";
|
|
646
|
-
|
|
684
|
+
const isOutput = operation === require_protocol.ConfigEditOperation.SET_OUTPUT || operation === require_protocol.ConfigEditOperation.REMOVE_OUTPUT;
|
|
685
|
+
if (!isOutput && (typeof plugin !== "string" || !plugin)) return "the edit names no plugin";
|
|
647
686
|
if (kind !== void 0 && (typeof kind !== "string" || !KINDS.has(kind))) return `unknown kind ${JSON.stringify(kind)}`;
|
|
648
687
|
if (kind !== void 0 && operation !== require_protocol.ConfigEditOperation.SET && operation !== require_protocol.ConfigEditOperation.REMOVE) return `${operation} edits the plugins array, so it takes no kind`;
|
|
649
|
-
if (operation === require_protocol.ConfigEditOperation.SET || operation === require_protocol.ConfigEditOperation.REMOVE) {
|
|
688
|
+
if (isOutput || operation === require_protocol.ConfigEditOperation.SET || operation === require_protocol.ConfigEditOperation.REMOVE) {
|
|
650
689
|
if (!Array.isArray(path) || !path.every((key) => typeof key === "string" && key)) return "path must be a list of option names";
|
|
651
690
|
if (!path.length) return "no option path given";
|
|
652
691
|
const unsafe = path.find((key) => !isSafeKey(key));
|
|
653
692
|
if (unsafe !== void 0) return `${unsafe} cannot be used as an option name`;
|
|
693
|
+
if (isOutput && !isOutputKey(path[0])) return `output.${path[0]} can only be changed in the config file`;
|
|
654
694
|
}
|
|
655
695
|
}
|
|
656
696
|
/** Where a node sits in the source text. */
|
|
@@ -951,9 +991,12 @@ function readPartial(node, prefix = []) {
|
|
|
951
991
|
}
|
|
952
992
|
/** The top-level options of a plugin call, each flagged with whether Studio may write it. */
|
|
953
993
|
function readOptions(call) {
|
|
954
|
-
const entries = {};
|
|
955
994
|
const options = call.arguments[0];
|
|
956
|
-
|
|
995
|
+
return options?.type === "ObjectExpression" ? readObject(options) : {};
|
|
996
|
+
}
|
|
997
|
+
/** The members of an object literal, each flagged with whether Studio may write it. */
|
|
998
|
+
function readObject(options) {
|
|
999
|
+
const entries = {};
|
|
957
1000
|
for (const [index, entry] of options.properties.entries()) {
|
|
958
1001
|
const key = memberKey(entry);
|
|
959
1002
|
if (key === void 0 || !isSafeKey(key)) continue;
|
|
@@ -1026,11 +1069,13 @@ function readConfig(source) {
|
|
|
1026
1069
|
});
|
|
1027
1070
|
const [adapter] = factoryCalls(mod, config, "adapter").map(toView);
|
|
1028
1071
|
const parsers = factoryCalls(mod, config, "parser").map(toView);
|
|
1072
|
+
const output = outputObject(config);
|
|
1029
1073
|
return {
|
|
1030
1074
|
name: configName(config),
|
|
1031
1075
|
plugins,
|
|
1032
1076
|
...adapter && { adapter },
|
|
1033
|
-
...parsers.length ? { parsers } : {}
|
|
1077
|
+
...parsers.length ? { parsers } : {},
|
|
1078
|
+
...!("reason" in output) && { output: pickOutput(readObject(output.object)) }
|
|
1034
1079
|
};
|
|
1035
1080
|
})
|
|
1036
1081
|
};
|
|
@@ -1079,6 +1124,16 @@ function applySet(source, call, path, value, quote) {
|
|
|
1079
1124
|
return { source: splice(source, closing, closing, printValue(nest(path, value), quote)) };
|
|
1080
1125
|
}
|
|
1081
1126
|
if (options.type !== "ObjectExpression") return { reason: "the factory was not called with an object literal" };
|
|
1127
|
+
return setIn({
|
|
1128
|
+
source,
|
|
1129
|
+
options,
|
|
1130
|
+
path,
|
|
1131
|
+
value,
|
|
1132
|
+
quote
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
/** Writes the literal `value` at `path` inside `options`, adding any intermediate object it needs. */
|
|
1136
|
+
function setIn({ source, options, path, value, quote }) {
|
|
1082
1137
|
const target = walk(options, path);
|
|
1083
1138
|
if ("reason" in target) return target;
|
|
1084
1139
|
if ("missing" in target) {
|
|
@@ -1096,6 +1151,34 @@ function applySetInput(source, config, input, quote) {
|
|
|
1096
1151
|
if (isShadowed(config, found.index)) return { reason: "a spread after input could override it" };
|
|
1097
1152
|
return { source: splice(source, rangeOf(found.member.value).start, rangeOf(found.member.value).end, value) };
|
|
1098
1153
|
}
|
|
1154
|
+
/** The config's root `output` object literal, or why Studio cannot edit inside it. */
|
|
1155
|
+
function outputObject(config) {
|
|
1156
|
+
const found = findMember(config, "output");
|
|
1157
|
+
if (found?.member.type !== "ObjectProperty" || found.member.value.type !== "ObjectExpression") return { reason: "output is not an object literal" };
|
|
1158
|
+
if (isShadowed(config, found.index)) return { reason: "a spread after output could override it" };
|
|
1159
|
+
return { object: found.member.value };
|
|
1160
|
+
}
|
|
1161
|
+
/** Writes or drops a member of the config's root `output` object. */
|
|
1162
|
+
function applyOutputEdit({ source, config, edit, quote }) {
|
|
1163
|
+
const output = outputObject(config);
|
|
1164
|
+
if ("reason" in output) return output;
|
|
1165
|
+
if (edit.operation === require_protocol.ConfigEditOperation.REMOVE_OUTPUT) return removeIn({
|
|
1166
|
+
source,
|
|
1167
|
+
options: output.object,
|
|
1168
|
+
path: edit.path
|
|
1169
|
+
});
|
|
1170
|
+
if (!isOptionValue(edit.value) || !isOutputValue({
|
|
1171
|
+
key: edit.path[0],
|
|
1172
|
+
value: nest(edit.path.slice(1), edit.value)
|
|
1173
|
+
})) return { reason: `the value is not one output.${edit.path[0]} takes` };
|
|
1174
|
+
return setIn({
|
|
1175
|
+
source,
|
|
1176
|
+
options: output.object,
|
|
1177
|
+
path: edit.path,
|
|
1178
|
+
value: edit.value,
|
|
1179
|
+
quote
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1099
1182
|
/**
|
|
1100
1183
|
* Deletes the option at `path`, falling the plugin back to its default for it. An option the file
|
|
1101
1184
|
* does not set already has its default, so removing it changes nothing.
|
|
@@ -1104,6 +1187,14 @@ function applyRemove(source, call, path) {
|
|
|
1104
1187
|
const options = call.arguments[0];
|
|
1105
1188
|
if (!options) return { source };
|
|
1106
1189
|
if (options.type !== "ObjectExpression") return { reason: "the factory was not called with an object literal" };
|
|
1190
|
+
return removeIn({
|
|
1191
|
+
source,
|
|
1192
|
+
options,
|
|
1193
|
+
path
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
/** Deletes the member at `path` inside `options`. A path that is not there already holds its default. */
|
|
1197
|
+
function removeIn({ source, options, path }) {
|
|
1107
1198
|
const target = walk(options, path);
|
|
1108
1199
|
if ("reason" in target) return target;
|
|
1109
1200
|
if ("missing" in target) return { source };
|
|
@@ -1193,6 +1284,12 @@ function applyEdit({ source, edit, quote, extensions }) {
|
|
|
1193
1284
|
const config = findConfig(parsed);
|
|
1194
1285
|
if (!config) return { reason: `no config entry found for ${JSON.stringify(ref)}` };
|
|
1195
1286
|
if (edit.operation === require_protocol.ConfigEditOperation.SET_INPUT) return applySetInput(source, config, edit.input, quote);
|
|
1287
|
+
if (edit.operation === require_protocol.ConfigEditOperation.SET_OUTPUT || edit.operation === require_protocol.ConfigEditOperation.REMOVE_OUTPUT) return applyOutputEdit({
|
|
1288
|
+
source,
|
|
1289
|
+
config,
|
|
1290
|
+
edit,
|
|
1291
|
+
quote
|
|
1292
|
+
});
|
|
1196
1293
|
if (edit.operation === require_protocol.ConfigEditOperation.DISABLE_PLUGIN) {
|
|
1197
1294
|
const result = disablePlugin(source, parsed.mod, config, edit.plugin);
|
|
1198
1295
|
if (!("reason" in result) || !result.reason.includes("shares a line")) return result;
|
|
@@ -2392,6 +2489,10 @@ var Agent = class extends capnweb.RpcTarget {
|
|
|
2392
2489
|
...config,
|
|
2393
2490
|
root,
|
|
2394
2491
|
input: checkout?.path ?? studioInput ?? config.input,
|
|
2492
|
+
output: mergeOutput({
|
|
2493
|
+
output: config.output,
|
|
2494
|
+
studio: patch?.output
|
|
2495
|
+
}),
|
|
2395
2496
|
storage: outputRoot ? stagingStorage({
|
|
2396
2497
|
root,
|
|
2397
2498
|
directory: outputRoot
|
|
@@ -2851,6 +2952,7 @@ function toEntryView(config, extensions) {
|
|
|
2851
2952
|
...config.name !== void 0 && { name: config.name },
|
|
2852
2953
|
...input !== void 0 && { input },
|
|
2853
2954
|
output: config.output.path,
|
|
2955
|
+
outputOptions: toJSONOptions(pickOutput(config.output)),
|
|
2854
2956
|
plugins: config.plugins.map((plugin) => ({
|
|
2855
2957
|
name: toStudioName({
|
|
2856
2958
|
name: (0, _kubb_core.resolveMeta)(plugin).name,
|