All files / packages/fds-uif/generator-lwc/src/blocks createPropertyApi.ts

68.18% Statements 15/22
66.66% Branches 6/9
100% Functions 1/1
68.18% Lines 15/22

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        17x             1x   1x 8x       1x   1x                     8x   8x 8x   8x 8x 8x                           17x 17x               17x    
import ts from 'typescript';
 
export function createPropertyApi(name: string, type: string, defaultValue: any) {
  // 1. Create the decorator node using ts.factory
  const apiDecoratorNode = ts.factory.createDecorator(
    ts.factory.createIdentifier("api"), // The name of the decorator
  );
  let normalizedType;
  let normalizedDefaultValue;
  // 2. Union types
  if (type.includes('|')) {
    const unionTypes = type.split(/\s*\|\s*/g);
    if (unionTypes[0].match(/^('|").*\1/)) {
      const literalTypeNodes = unionTypes.map((literal) => 
        ts.factory.createLiteralTypeNode(
          ts.factory.createStringLiteral(literal.replace(/^('|")(.*)\1/, '$2'))
        )
      );
      normalizedDefaultValue = ts.factory.createStringLiteral(defaultValue);
      // 3. Create the UnionTypeNode from the array of literal types
      normalizedType = ts.factory.createUnionTypeNode(literalTypeNodes);
    } else {
      throw `unknown union ${type}`;
    }
  } else {
    // 2. Non union types
    switch (type) {
      case 'boolean':
        if (!!defaultValue) {
          normalizedDefaultValue = ts.factory.createTrue();
        } else {
          normalizedDefaultValue = ts.factory.createFalse();
        }
        normalizedType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
        break;
      case 'string':
        normalizedDefaultValue = ts.factory.createStringLiteral(defaultValue);
        normalizedType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
        break;
      case 'number':
        normalizedDefaultValue = ts.factory.createNumericLiteral(defaultValue);
        normalizedType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
        break;
      case 'ReactNode':
        // no-op, slots are not exposed in LWC via a prop
        return null;
      default:
        throw `unknown type ${type}`;
    }
  }
 
  // 3. Create the property declaration with the decorator
  const isBoolean = type === 'boolean';
  const propertyDeclaration = ts.factory.createPropertyDeclaration(
    [apiDecoratorNode], // Decorators array
    ts.factory.createIdentifier(name), // Property name 'foo'
    undefined, // question token
    normalizedType, // Optional type (e.g., ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
    !isBoolean && defaultValue === undefined ? undefined : normalizedDefaultValue // Initial value (optional)
  );
 
  return propertyDeclaration;
}