everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
104 lines (103 loc) • 3.36 kB
JavaScript
//#region src/cli/parse.ts
function unwrap(schema) {
let current = schema;
while (true) {
const type = current._def?.type;
if (type === "default" || type === "optional" || type === "nullable" || type === "nullish") {
const inner = current._def?.innerType;
if (!inner) break;
current = inner;
continue;
}
return current;
}
return current;
}
function isBooleanSchema(schema) {
return unwrap(schema)._def?.type === "boolean";
}
function isArraySchema(schema) {
return unwrap(schema)._def?.type === "array";
}
function coerceValue(raw, schema) {
switch (unwrap(schema)._def?.type) {
case "boolean": return raw === "true" || raw === "1" || raw === "yes";
case "number": {
const value = Number(raw);
if (Number.isNaN(value)) throw new Error(`Invalid number: ${raw}`);
return value;
}
case "enum": return raw;
default: return raw;
}
}
function toFlagName(field) {
return `--${field.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase()}`;
}
function getShape(schema) {
const shape = unwrap(schema)._def?.shape;
if (!shape) return {};
return shape;
}
function parseCommandInput(descriptor, argv) {
const schema = descriptor.procedure["~orpc"]?.inputSchema;
if (!schema) return {};
const shape = getShape(schema);
const fields = Object.entries(shape);
const fieldByFlag = /* @__PURE__ */ new Map();
const positionalFields = [];
for (const [fieldName] of fields) {
fieldByFlag.set(toFlagName(fieldName), fieldName);
if (descriptor.meta.fields?.[fieldName]?.positional) positionalFields.push(fieldName);
}
const input = {};
const positionals = [];
for (let i = 0; i < argv.length; i += 1) {
const token = argv[i];
if (!token) continue;
if (token.startsWith("--no-")) {
const flagName = `--${token.slice(5)}`;
const fieldName = fieldByFlag.get(flagName);
if (!fieldName) throw new Error(`Unknown flag: ${token}`);
input[fieldName] = false;
continue;
}
if (token.startsWith("--")) {
const [flag, inline] = token.split("=", 2);
const fieldName = fieldByFlag.get(flag);
if (!fieldName) throw new Error(`Unknown flag: ${token}`);
const fieldSchema = shape[fieldName];
if (isBooleanSchema(fieldSchema)) {
input[fieldName] = inline ? coerceValue(inline, fieldSchema) : true;
continue;
}
const next = inline ?? argv[i + 1];
if (isArraySchema(fieldSchema)) {
if (next === void 0 || next.startsWith("--")) throw new Error(`Missing value for ${flag}`);
input[fieldName] = next.split(",").map((s) => s.trim()).filter(Boolean);
if (!inline) i += 1;
continue;
}
if (next === void 0 || next.startsWith("--")) throw new Error(`Missing value for ${flag}`);
input[fieldName] = coerceValue(next, fieldSchema);
if (!inline) i += 1;
continue;
}
positionals.push(token);
}
if (positionalFields.length > 0) positionalFields.forEach((fieldName, index) => {
const raw = positionals[index];
if (raw !== void 0) input[fieldName] = coerceValue(raw, shape[fieldName]);
});
else if (positionals.length > 0) {
const candidate = fields.find(([, fieldSchema]) => !isBooleanSchema(fieldSchema));
if (candidate) {
const [fieldName, fieldSchema] = candidate;
input[fieldName] = coerceValue(positionals[0], fieldSchema);
}
}
return schema.parse(input);
}
//#endregion
export { parseCommandInput };
//# sourceMappingURL=parse.mjs.map