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        66x                 66x 66x 12x 38x   12x   12x 54x 1x     53x   34x 1x   33x   34x 34x   16x 16x 16x   1x 1x 1x     1x   1x         63x 63x               66x    
import { factory, SyntaxKind } from '../utils/ts7.js';
 
export function createPropertyApi(name: string, type: string, defaultValue: any) {
  // 1. Create the decorator node using the factory
  const apiDecoratorNode = factory.createDecorator(
    factory.createIdentifier('api'), // The name of the decorator
  );
  let normalizedType;
  let normalizedDefaultValue;
  // 2. String-literal types — either a single literal (`'salesforce1'`, e.g. a
  // one-option variant) or a union of them (`'brand' | 'destructive'`). Split
  // on `|` and emit one literal node per member; a single member prints as the
  // bare literal with no pipe.
  const members = type.split(/\s*\|\s*/g);
  if (members[0].match(/^('|").*\1$/)) {
    const literalTypeNodes = members.map((literal) =>
      factory.createLiteralTypeNode(factory.createStringLiteral(literal.replace(/^('|")(.*)\1$/, '$2'))),
    );
    normalizedDefaultValue = factory.createStringLiteral(defaultValue);
    // 3. Create the UnionTypeNode from the array of literal types
    normalizedType = factory.createUnionTypeNode(literalTypeNodes);
  } else if (type.includes('|')) {
    throw `unknown union ${type}`;
  } else {
    // 2. Non union types
    switch (type) {
      case 'boolean':
        if (!!defaultValue) {
          normalizedDefaultValue = factory.createTrue();
        } else {
          normalizedDefaultValue = factory.createFalse();
        }
        normalizedType = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword);
        break;
      case 'string':
        normalizedDefaultValue = factory.createStringLiteral(defaultValue);
        normalizedType = factory.createKeywordTypeNode(SyntaxKind.StringKeyword);
        break;
      case 'number':
        normalizedDefaultValue = factory.createNumericLiteral(defaultValue);
        normalizedType = factory.createKeywordTypeNode(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 = factory.createPropertyDeclaration(
    [apiDecoratorNode], // Decorators array
    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;
}