Skip to content

Commit

Permalink
build: account for object literal syntax when extracting inputs
Browse files Browse the repository at this point in the history
Fixes that the build was throwing an error when using the object literal syntax for the `inputs` array.

(cherry picked from commit 616d44c)
  • Loading branch information
crisbeto committed Feb 22, 2024
1 parent acd214b commit 0a84ef9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 29 deletions.
57 changes: 31 additions & 26 deletions tools/dgeni/common/directive-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
import {
ArrayLiteralExpression,
CallExpression,
isCallExpression,
NodeArray,
ObjectLiteralExpression,
PropertyAssignment,
StringLiteral,
SyntaxKind,
getDecorators,
isClassDeclaration,
} from 'typescript';
import ts from 'typescript';
import {CategorizedClassDoc} from './dgeni-definitions';

/**
Expand All @@ -30,15 +19,15 @@ import {CategorizedClassDoc} from './dgeni-definitions';
export function getDirectiveMetadata(classDoc: CategorizedClassDoc): Map<string, any> | null {
const declaration = classDoc.symbol.valueDeclaration;
const decorators =
declaration && isClassDeclaration(declaration) ? getDecorators(declaration) : null;
declaration && ts.isClassDeclaration(declaration) ? ts.getDecorators(declaration) : null;

if (!decorators?.length) {
return null;
}

const expression = decorators
.filter(decorator => decorator.expression && isCallExpression(decorator.expression))
.map(decorator => decorator.expression as CallExpression)
.filter(decorator => decorator.expression && ts.isCallExpression(decorator.expression))
.map(decorator => decorator.expression as ts.CallExpression)
.find(
callExpression =>
callExpression.expression.getText() === 'Component' ||
Expand All @@ -55,25 +44,41 @@ export function getDirectiveMetadata(classDoc: CategorizedClassDoc): Map<string,
return null;
}

const objectExpression = expression.arguments[0] as ObjectLiteralExpression;
const objectExpression = expression.arguments[0] as ts.ObjectLiteralExpression;
const resultMetadata = new Map<string, any>();

(objectExpression.properties as NodeArray<PropertyAssignment>).forEach(prop => {
(objectExpression.properties as ts.NodeArray<ts.PropertyAssignment>).forEach(prop => {
// Support ArrayLiteralExpression assignments in the directive metadata.
if (prop.initializer.kind === SyntaxKind.ArrayLiteralExpression) {
const arrayData = (prop.initializer as ArrayLiteralExpression).elements.map(
literal => (literal as StringLiteral).text,
);
if (ts.isArrayLiteralExpression(prop.initializer)) {
const arrayData = prop.initializer.elements.map(literal => {
if (ts.isStringLiteralLike(literal)) {
return literal.text;
}

if (ts.isObjectLiteralExpression(literal)) {
return literal.properties.reduce(
(result, prop) => {
if (ts.isPropertyAssignment(prop)) {
result[prop.name.getText()] = ts.isStringLiteralLike(prop.initializer)
? prop.initializer.text
: prop.initializer.getText();
}

return result;
},
{} as Record<string, string>,
);
}

return literal.getText();
});

resultMetadata.set(prop.name.getText(), arrayData);
}

// Support normal StringLiteral and NoSubstitutionTemplateLiteral assignments
if (
prop.initializer.kind === SyntaxKind.StringLiteral ||
prop.initializer.kind === SyntaxKind.NoSubstitutionTemplateLiteral
) {
resultMetadata.set(prop.name.getText(), (prop.initializer as StringLiteral).text);
if (ts.isStringLiteralLike(prop.initializer)) {
resultMetadata.set(prop.name.getText(), prop.initializer.text);
}
});

Expand Down
13 changes: 10 additions & 3 deletions tools/dgeni/common/property-bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,20 @@ function getBindingPropertyData(
decoratorName: string,
) {
if (metadata) {
const metadataValues: string[] = metadata.get(propertyName) || [];
const foundValue = metadataValues.find(value => value.split(':')[0] === doc.name);
const metadataValues: (string | {name: string; alias?: string})[] =
metadata.get(propertyName) || [];
const foundValue = metadataValues.find(value => {
const name = typeof value === 'string' ? value.split(':')[0] : value.name;
return name === doc.name;
});

if (foundValue) {
return {
name: doc.name,
alias: foundValue.split(':')[1],
alias:
typeof foundValue === 'string'
? foundValue.split(':')[1]
: foundValue.alias || foundValue.name,
};
}
}
Expand Down

0 comments on commit 0a84ef9

Please sign in to comment.