All files print-contract.ts

41.93% Statements 13/31
30.35% Branches 17/56
50% Functions 1/2
42.85% Lines 12/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70            5x   5x         5x 5x                 5x 5x 5x   5x 5x 6x   5x 5x                                                                          
import type { ModelNode } from '@contractkit/core';
import { printField, printInlineObjectExpanded, extractTrailingInlineObject, printType, printEnumExpanded } from './print-type.js';
import { INDENT } from './indent.js';
 
// ─── Model declaration ───────────────────────────────────────────────────────
 
export function printModelDecl(model: ModelNode, printWidth: number = 80): string {
    // Type alias form: Name : typeExpression
    Iif (model.type !== undefined) {
        return printTypeAlias(model, printWidth);
    }
 
    // Regular model with fields (possibly inherited)
    const commentSuffix = model.description ? ` # ${model.description}` : '';
    const modifiers = [
        model.deprecated ? 'deprecated' : '',
        model.inputCase || model.outputCase
            ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`
            : '',
        model.mode ? `mode(${model.mode})` : '',
    ]
        .filter(Boolean)
        .join(' ');
    const modePrefix = modifiers ? `${modifiers} ` : '';
    const baseChain = model.bases && model.bases.length > 0 ? `${model.bases.join(' & ')} & ` : '';
    const header = `${modePrefix}${model.name}: ${baseChain}{${commentSuffix}`;
 
    const lines: string[] = [header];
    for (Iconst field of model.fields) {
        lines.push(printField(field, INDENT, printWidth));
    }
    lines.push('}');
    return lines.join('\n');
}
 
function printTypeAlias(model: ModelNode, printWidth: number): string {
    const type = model.type!;
    const commentSuffix = model.description ? ` # ${model.description}` : '';
    const modifiers = [
        model.deprecated ? 'deprecated' : '',
        model.inputCase || model.outputCase
            ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`
            : '',
        model.mode ? `mode(${model.mode})` : '',
    ]
        .filter(Boolean)
        .join(' ');
    const modePrefix = modifiers ? `${modifiers} ` : '';
 
    // If the type ends with an inline brace object, expand it as a pseudo-model block.
    const trailing = extractTrailingInlineObject(type);
    if (trailing) {
        const { prefix, inlineObj } = trailing;
        const modePart = inlineObj.mode ? `mode(${inlineObj.mode}) ` : '';
        const header = prefix
            ? `${modePrefix}${model.name}: ${prefix} & ${modePart}{${commentSuffix}`
            : `${modePrefix}${model.name}: ${modePart}{${commentSuffix}`;
        const lines: string[] = [header, ...printInlineObjectExpanded(inlineObj, INDENT, printWidth), '}'];
        return lines.join('\n');
    }
 
    // Simple type alias — single line, unless it's a long enum.
    // Note: the contract prefix "contract " (9 chars) is prepended by the caller.
    const singleLine = `${modePrefix}${model.name}: ${printType(type)}${commentSuffix}`;
    if (type.kind === 'enum' && 'contract '.length + singleLine.length > printWidth) {
        return `${modePrefix}${model.name}: ${printEnumExpanded(type.values, '')}${commentSuffix}`;
    }
    return singleLine;
}