Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ssr-compiler): validate api decorator usage #5071

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

cardoso
Copy link
Contributor

@cardoso cardoso commented Dec 20, 2024

Details

I'm a bit short on time today to finish polishing this up, so I'm sending this as a draft.

Follow up to #5062
Partially addresses #5032

This PR aims to replicate the api decorator validation done in babel-plugin-component and also related tests.

Some of the validation done in babel-plugin-component seems to be done after everything is collected, while here it's currently all done during traversal. Maybe that's just for better error reporting, which I think can be considered in a separate issue, but need to make sure this is not introducing undesirable behavior here.

TODOS:

  • Move decorator validation logic to separate folder or file
  • Replicate the valid tests to make sure no extra errors are introduced
  • (?) Move copied constants to @lwc/shared or @lwc/errors
  • (?) Add filename to ComponentMetaState in order to replicate the error structure
  • (?) Add loc to error structure (line, column, start, length)

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.
  • 💔 Yes, it does introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.
  • 🔬 Yes, it does include an observable change.

GUS work item

@cardoso cardoso requested a review from a team as a code owner December 20, 2024 17:08
@cardoso cardoso marked this pull request as draft December 20, 2024 17:08
Comment on lines 188 to 203
const field = state.publicFields.get(node.key.name);

if (field) {
if (
(is.methodDefinition(field, { kind: (k) => k === 'get' || k === 'set' }) &&
node.kind === 'get') ||
node.kind === 'set'
) {
throw generateError(
DecoratorErrors.SINGLE_DECORATOR_ON_SETTER_GETTER_PAIR,
node.key.name
);
} else {
throw generateError(DecoratorErrors.DUPLICATE_API_PROPERTY, node.key.name);
}
}
Copy link
Contributor Author

@cardoso cardoso Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean this up & move to its own function

Comment on lines 333 to 368

function isBooleanPropDefaultTrue(property: EsPropertyDefinition) {
const propertyValue = property.value;
return propertyValue && propertyValue.type === 'Literal' && propertyValue.value === true;
}

function validatePropertyValue(property: EsPropertyDefinition) {
if (isBooleanPropDefaultTrue(property)) {
throw generateError(DecoratorErrors.INVALID_BOOLEAN_PUBLIC_PROPERTY);
}
}

function validatePropertyName(property: EsMethodDefinition | EsPropertyDefinition) {
if (property.computed || !('name' in property.key)) {
throw generateError(DecoratorErrors.PROPERTY_CANNOT_BE_COMPUTED);
}

const propertyName = property.key.name;

switch (true) {
case propertyName === 'part':
throw generateError(DecoratorErrors.PROPERTY_NAME_PART_IS_RESERVED, propertyName);
case propertyName.startsWith('on'):
throw generateError(DecoratorErrors.PROPERTY_NAME_CANNOT_START_WITH_ON, propertyName);
case propertyName.startsWith('data') && propertyName.length > 4:
throw generateError(DecoratorErrors.PROPERTY_NAME_CANNOT_START_WITH_DATA, propertyName);
case DISALLOWED_PROP_SET.has(propertyName):
throw generateError(DecoratorErrors.PROPERTY_NAME_IS_RESERVED, propertyName);
case AMBIGUOUS_PROP_SET.has(propertyName):
throw generateError(
DecoratorErrors.PROPERTY_NAME_IS_AMBIGUOUS,
propertyName,
AMBIGUOUS_PROP_SET.get(propertyName)!
);
}
}
Copy link
Contributor Author

@cardoso cardoso Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean this up & move to a separate file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant