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

93.33% Statements 28/30
83.33% Branches 5/6
100% Functions 5/5
92.85% Lines 26/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 71 72 73 74 75 76 77 78                        15x 15x   15x       15x   15x 48x 33x 33x 33x         48x   15x 15x 5x   15x 1x     15x 15x 1x     15x                     15x       15x 15x   15x           15x 15x 15x            
import ts from 'typescript';
 
import { PropMetadata, type ComponentMetadata } from '@fds-uif/generator-base';
 
import { createPropertyApi } from './blocks/createPropertyApi.js';
import { createLwcImportStatement } from './blocks/createLwcImportStatement.js';
import { createClassGetter } from './blocks/createClassGetter.js';
import { createRenderWhenGetter } from './blocks/createRenderWhenGetter.js';
import { buildClassGetterPlan } from './utils/classGetterPlan.js';
import { buildRenderWhenPlan } from './utils/renderWhenPlan.js';
 
function createComponentClass(metadata: ComponentMetadata) {
  const className = metadata.name;
  const baseClass = ts.factory.createIdentifier('LightningElement');
 
  const heritageClause = ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
    ts.factory.createExpressionWithTypeArguments(baseClass, []),
  ]);
 
  const classBody = [] as ts.ClassElement[];
 
  metadata.props.forEach((prop: PropMetadata) => {
    if (prop.source !== 'slot') {
      const api = createPropertyApi(prop.name, prop.type, prop.default);
      Eif (api) {
        classBody.push(api);
      }
    }
  });
 
  const propNames = new Set(metadata.props.filter((p) => p.source !== 'slot').map((p) => p.name));
 
  const classPlan = buildClassGetterPlan(metadata);
  if (classPlan.rootGetterName) {
    classBody.push(createClassGetter(classPlan.rootGetterName, classPlan.rootRules, propNames));
  }
  for (const { name, rules } of classPlan.nodes.values()) {
    classBody.push(createClassGetter(name, rules, propNames));
  }
 
  const rwPlan = buildRenderWhenPlan(metadata);
  for (const g of rwPlan.getters) {
    classBody.push(createRenderWhenGetter(g.name, g.match));
  }
 
  const classDeclaration = ts.factory.createClassDeclaration(
    [
      ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
      ts.factory.createModifier(ts.SyntaxKind.DefaultKeyword),
    ],
    ts.factory.createIdentifier(className),
    undefined,
    [heritageClause],
    classBody,
  );
 
  return classDeclaration;
}
 
export function generateClass(metadata: ComponentMetadata): string {
  const lwcImportStatement = createLwcImportStatement(metadata);
  const lwcComponentClass = createComponentClass(metadata);
 
  const sourceFile = ts.factory.createSourceFile(
    [lwcImportStatement, lwcComponentClass],
    ts.factory.createToken(ts.SyntaxKind.EndOfFileToken),
    ts.NodeFlags.None,
  );
 
  const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
  try {
    return printer.printFile(sourceFile);
  } catch (error) {
    console.log(error);
    throw error;
  }
}