Skip to content

Commit

Permalink
fix(ssr-compiler): protect internals from userland (#4679)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekashida authored Oct 22, 2024
1 parent 7238cfc commit 762723c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
8 changes: 6 additions & 2 deletions packages/@lwc/ssr-compiler/src/compile-js/generate-markup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const bGenerateMarkup = esTemplate`
const instance = new ${is.identifier}({
tagName: tagName.toUpperCase(),
});
instance.__internal__setState(props, __REFLECTED_PROPS__, attrs);
instance[__SYMBOL__SET_INTERNALS](props, __REFLECTED_PROPS__, attrs);
instance.isConnected = true;
instance.connectedCallback?.();
const tmplFn = ${isIdentOrRenderCall} ?? __fallbackTmpl;
Expand All @@ -53,7 +53,11 @@ const bGenerateMarkup = esTemplate`
`<ExportNamedDeclaration>;

const bInsertFallbackTmplImport = esTemplate`
import { fallbackTmpl as __fallbackTmpl, renderAttrs as __renderAttrs } from '@lwc/ssr-runtime';
import {
fallbackTmpl as __fallbackTmpl,
renderAttrs as __renderAttrs,
SYMBOL__SET_INTERNALS as __SYMBOL__SET_INTERNALS,
} from '@lwc/ssr-runtime';
`<ImportDeclaration>;

const bCreateReflectedPropArr = esTemplate`
Expand Down
6 changes: 5 additions & 1 deletion packages/@lwc/ssr-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
*/

export { ClassList } from './class-list';
export { LightningElement, LightningElementConstructor } from './lightning-element';
export {
LightningElement,
LightningElementConstructor,
SYMBOL__SET_INTERNALS,
} from './lightning-element';
export { MutationTracker } from './mutation-tracker';
// renderComponent is an alias for serverSideRenderComponent
export {
Expand Down
26 changes: 14 additions & 12 deletions packages/@lwc/ssr-runtime/src/lightning-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,33 @@ interface PropsAvailableAtConstruction {
tagName: string;
}

export const SYMBOL__SET_INTERNALS = Symbol('set-internals');

export class LightningElement implements PropsAvailableAtConstruction {
static renderMode?: 'light' | 'shadow';

isConnected = false;
className = '';
// TODO [W-14977927]: protect internals from userland
private __attrs!: Attributes;
private __classList: ClassList | null = null;

// Using ! because it's assigned in the constructor via `Object.assign`, which TS can't detect
tagName!: string;

#attrs!: Attributes;
#classList: ClassList | null = null;

constructor(
propsAvailableAtConstruction: PropsAvailableAtConstruction & Record<string, unknown>
) {
Object.assign(this, propsAvailableAtConstruction);
}

// TODO [W-14977927]: protect internals from userland
private __internal__setState(
[SYMBOL__SET_INTERNALS](
props: Record<string, any>,
reflectedProps: string[],
attrs: Record<string, any>
) {
Object.assign(this, props);
this.__attrs = attrs;
this.#attrs = attrs;

// Whenever a reflected prop changes, we'll update the original props object
// that was passed in. That'll be referenced when the attrs are rendered later.
Expand Down Expand Up @@ -83,14 +85,14 @@ export class LightningElement implements PropsAvailableAtConstruction {
}

get classList() {
if (this.__classList) {
return this.__classList;
if (this.#classList) {
return this.#classList;
}
return (this.__classList = new ClassList(this));
return (this.#classList = new ClassList(this));
}

#setAttribute(attrName: string, attrValue: string | null): void {
this.__attrs[attrName] = attrValue;
this.#attrs[attrName] = attrValue;
mutationTracker.add(this, attrName);
}

Expand All @@ -100,13 +102,13 @@ export class LightningElement implements PropsAvailableAtConstruction {

getAttribute(attrName: unknown): string | null {
if (this.hasAttribute(attrName)) {
return this.__attrs[attrName as string];
return this.#attrs[attrName as string];
}
return null;
}

hasAttribute(attrName: unknown): boolean {
return typeof attrName === 'string' && typeof this.__attrs[attrName] === 'string';
return typeof attrName === 'string' && typeof this.#attrs[attrName] === 'string';
}

removeAttribute(attrName: string): void {
Expand Down

0 comments on commit 762723c

Please sign in to comment.