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

100% Statements 26/26
100% Branches 15/15
100% Functions 2/2
100% Lines 26/26

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        42x           42x 5x 5x 4x 17x       4x   4x   1x       37x   20x 1x   19x   20x 20x   14x 14x 14x   1x 1x 1x     1x   1x         39x 39x               42x    
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;
}