EdgeAIG's picture
download
raw
5.55 kB
/**
* Config Internal
* ================
*
* The processed internal representation of a Command.Config declaration.
* Separates the user's declared config shape from the flat parsing representation.
*
* Key concepts:
* - ConfigInternal: The full processed form (flags, arguments, tree)
* - ConfigInternal.Tree: Maps declaration keys to nodes
* - ConfigInternal.Node: Param reference, Array, or Nested subtree
*
* Example transformation from Command.Config to Command.Config.Internal:
*
* ```ts
* // User declares:
* const config = {
* verbose: Flag.boolean("verbose"),
* server: {
* host: Flag.string("host"),
* port: Flag.integer("port")
* },
* files: Argument.string("files").pipe(Argument.variadic)
* }
*
* // Becomes Config.Internal:
* {
* arguments: [filesParam], // Flat array of arguments
* flags: [verboseParam, hostParam, portParam], // Flat array of flags
* orderedParams: [verboseParam, hostParam, portParam, filesParam],
* tree: { // Preserves nested structure
* verbose: { _tag: "Param", index: 0 },
* server: {
* _tag: "Nested",
* tree: {
* host: { _tag: "Param", index: 1 },
* port: { _tag: "Param", index: 2 }
* }
* },
* files: { _tag: "Param", index: 3 }
* }
* }
* ```
*
* This separation allows:
* 1. Flat iteration over all params for parsing/validation
* 2. Reconstruction of original nested shape for handler input
*/
import * as Predicate from "../../../Predicate.js";
import * as Param from "../Param.js";
/* ========================================================================== */
/* Type ID */
/* ========================================================================== */
const ConfigInternalTypeId = "~effect/cli/Command/Config/Internal";
/* ========================================================================== */
/* Guards */
/* ========================================================================== */
/** @internal */
export const isConfigInternal = u => Predicate.hasProperty(u, ConfigInternalTypeId);
/**
* Parses a Command.Config into a ConfigInternal.
*
* Walks the config structure and:
* 1. Extracts all Params into flat arrays (flags, arguments, orderedParams)
* 2. Builds a tree that remembers the original nested structure
* 3. Assigns each Param an index to link parsed values back
*
* @internal
*/
export const parseConfig = config => {
const orderedParams = [];
const flags = [];
const args = [];
function parse(config) {
const tree = {};
for (const key in config) {
tree[key] = parseValue(config[key]);
}
return tree;
}
function parseValue(value) {
if (Array.isArray(value)) {
return {
_tag: "Array",
children: value.map(v => parseValue(v))
};
} else if (Param.isParam(value)) {
const index = orderedParams.length;
orderedParams.push(value);
if (value.kind === "argument") {
args.push(value);
} else {
flags.push(value);
}
return {
_tag: "Param",
index
};
} else {
return {
_tag: "Nested",
tree: parse(value)
};
}
}
return {
[ConfigInternalTypeId]: ConfigInternalTypeId,
flags,
arguments: args,
orderedParams,
tree: parse(config)
};
};
/** @internal */
export const emptyConfig = /*#__PURE__*/parseConfig({});
const shiftNodeIndexes = (node, offset) => {
switch (node._tag) {
case "Param":
return {
_tag: "Param",
index: node.index + offset
};
case "Array":
return {
_tag: "Array",
children: node.children.map(child => shiftNodeIndexes(child, offset))
};
case "Nested":
return {
_tag: "Nested",
tree: shiftTreeIndexes(node.tree, offset)
};
}
};
const shiftTreeIndexes = (tree, offset) => {
const output = {};
for (const key in tree) {
output[key] = shiftNodeIndexes(tree[key], offset);
}
return output;
};
/** @internal */
export const mergeConfig = (left, right) => {
const offset = left.orderedParams.length;
return {
[ConfigInternalTypeId]: ConfigInternalTypeId,
flags: [...left.flags, ...right.flags],
arguments: [...left.arguments, ...right.arguments],
orderedParams: [...left.orderedParams, ...right.orderedParams],
tree: {
...left.tree,
...shiftTreeIndexes(right.tree, offset)
}
};
};
/* ========================================================================== */
/* Reconstruction */
/* ========================================================================== */
/**
* Reconstructs the original nested config shape from parsed values.
*
* Uses the tree as a blueprint to place each parsed value back into
* its original position in the nested structure.
*
* @internal
*/
export const reconstructTree = (tree, results) => {
const output = {};
for (const key in tree) {
output[key] = nodeValue(tree[key]);
}
return output;
function nodeValue(node) {
switch (node._tag) {
case "Param":
return results[node.index];
case "Array":
return node.children.map(child => nodeValue(child));
case "Nested":
return reconstructTree(node.tree, results);
}
}
};
//# sourceMappingURL=config.js.map

Xet Storage Details

Size:
5.55 kB
·
Xet hash:
3e9e8624a94792e97dfdba799f3448b94281c36da8919a3de0e6d1afe21bc12d

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.